ActivityManagerService.java revision 8920e1cabb56be6c46df40f5329aadbce3132fde
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 org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ITaskStackListener;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.SELinux;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.UpdateLock;
187import android.os.UserHandle;
188import android.os.UserManager;
189import android.provider.Settings;
190import android.text.format.DateUtils;
191import android.text.format.Time;
192import android.util.AtomicFile;
193import android.util.EventLog;
194import android.util.Log;
195import android.util.Pair;
196import android.util.PrintWriterPrinter;
197import android.util.Slog;
198import android.util.SparseArray;
199import android.util.TimeUtils;
200import android.util.Xml;
201import android.view.Gravity;
202import android.view.LayoutInflater;
203import android.view.View;
204import android.view.WindowManager;
205
206import dalvik.system.VMRuntime;
207
208import java.io.BufferedInputStream;
209import java.io.BufferedOutputStream;
210import java.io.DataInputStream;
211import java.io.DataOutputStream;
212import java.io.File;
213import java.io.FileDescriptor;
214import java.io.FileInputStream;
215import java.io.FileNotFoundException;
216import java.io.FileOutputStream;
217import java.io.IOException;
218import java.io.InputStreamReader;
219import java.io.PrintWriter;
220import java.io.StringWriter;
221import java.lang.ref.WeakReference;
222import java.util.ArrayList;
223import java.util.Arrays;
224import java.util.Collections;
225import java.util.Comparator;
226import java.util.HashMap;
227import java.util.HashSet;
228import java.util.Iterator;
229import java.util.List;
230import java.util.Locale;
231import java.util.Map;
232import java.util.Set;
233import java.util.concurrent.atomic.AtomicBoolean;
234import java.util.concurrent.atomic.AtomicLong;
235
236public final class ActivityManagerService extends ActivityManagerNative
237        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
238
239    private static final String USER_DATA_DIR = "/data/user/";
240    // File that stores last updated system version and called preboot receivers
241    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
242
243    static final String TAG = "ActivityManager";
244    static final String TAG_MU = "ActivityManagerServiceMU";
245    static final boolean DEBUG = false;
246    static final boolean localLOGV = DEBUG;
247    static final boolean DEBUG_BACKUP = localLOGV || false;
248    static final boolean DEBUG_BROADCAST = localLOGV || false;
249    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_CLEANUP = localLOGV || false;
252    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
253    static final boolean DEBUG_FOCUS = false;
254    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
255    static final boolean DEBUG_MU = localLOGV || false;
256    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
257    static final boolean DEBUG_LRU = localLOGV || false;
258    static final boolean DEBUG_PAUSE = localLOGV || false;
259    static final boolean DEBUG_POWER = localLOGV || false;
260    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
261    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
262    static final boolean DEBUG_PROCESSES = localLOGV || false;
263    static final boolean DEBUG_PROVIDER = localLOGV || false;
264    static final boolean DEBUG_RESULTS = localLOGV || false;
265    static final boolean DEBUG_SERVICE = localLOGV || false;
266    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
267    static final boolean DEBUG_STACK = localLOGV || false;
268    static final boolean DEBUG_SWITCH = localLOGV || false;
269    static final boolean DEBUG_TASKS = localLOGV || false;
270    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
271    static final boolean DEBUG_TRANSITION = localLOGV || false;
272    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
273    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
274    static final boolean DEBUG_VISBILITY = localLOGV || false;
275    static final boolean DEBUG_PSS = localLOGV || false;
276    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
277    static final boolean DEBUG_RECENTS = localLOGV || false;
278    static final boolean VALIDATE_TOKENS = false;
279    static final boolean SHOW_ACTIVITY_START_TIME = true;
280
281    // Control over CPU and battery monitoring.
282    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
283    static final boolean MONITOR_CPU_USAGE = true;
284    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
285    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
286    static final boolean MONITOR_THREAD_CPU_USAGE = false;
287
288    // The flags that are set for all calls we make to the package manager.
289    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
290
291    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
292
293    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
294
295    // Maximum number recent bitmaps to keep in memory.
296    static final int MAX_RECENT_BITMAPS = 3;
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_BACKGROUND_BROADCAST) {
405            Slog.i(TAG, "Broadcast intent " + intent + " on "
406                    + (isFg ? "foreground" : "background")
407                    + " queue");
408        }
409        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
410    }
411
412    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
413        for (BroadcastQueue queue : mBroadcastQueues) {
414            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
415            if (r != null) {
416                return r;
417            }
418        }
419        return null;
420    }
421
422    /**
423     * Activity we have told the window manager to have key focus.
424     */
425    ActivityRecord mFocusedActivity = null;
426
427    /**
428     * List of intents that were used to start the most recent tasks.
429     */
430    ArrayList<TaskRecord> mRecentTasks;
431    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
432
433    /**
434     * For addAppTask: cached of the last activity component that was added.
435     */
436    ComponentName mLastAddedTaskComponent;
437
438    /**
439     * For addAppTask: cached of the last activity uid that was added.
440     */
441    int mLastAddedTaskUid;
442
443    /**
444     * For addAppTask: cached of the last ActivityInfo that was added.
445     */
446    ActivityInfo mLastAddedTaskActivity;
447
448    public class PendingAssistExtras extends Binder implements Runnable {
449        public final ActivityRecord activity;
450        public final Bundle extras;
451        public final Intent intent;
452        public final String hint;
453        public final int userHandle;
454        public boolean haveResult = false;
455        public Bundle result = null;
456        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
457                String _hint, int _userHandle) {
458            activity = _activity;
459            extras = _extras;
460            intent = _intent;
461            hint = _hint;
462            userHandle = _userHandle;
463        }
464        @Override
465        public void run() {
466            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
467            synchronized (this) {
468                haveResult = true;
469                notifyAll();
470            }
471        }
472    }
473
474    final ArrayList<PendingAssistExtras> mPendingAssistExtras
475            = new ArrayList<PendingAssistExtras>();
476
477    /**
478     * Process management.
479     */
480    final ProcessList mProcessList = new ProcessList();
481
482    /**
483     * All of the applications we currently have running organized by name.
484     * The keys are strings of the application package name (as
485     * returned by the package manager), and the keys are ApplicationRecord
486     * objects.
487     */
488    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
489
490    /**
491     * Tracking long-term execution of processes to look for abuse and other
492     * bad app behavior.
493     */
494    final ProcessStatsService mProcessStats;
495
496    /**
497     * The currently running isolated processes.
498     */
499    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
500
501    /**
502     * Counter for assigning isolated process uids, to avoid frequently reusing the
503     * same ones.
504     */
505    int mNextIsolatedProcessUid = 0;
506
507    /**
508     * The currently running heavy-weight process, if any.
509     */
510    ProcessRecord mHeavyWeightProcess = null;
511
512    /**
513     * The last time that various processes have crashed.
514     */
515    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
516
517    /**
518     * Information about a process that is currently marked as bad.
519     */
520    static final class BadProcessInfo {
521        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
522            this.time = time;
523            this.shortMsg = shortMsg;
524            this.longMsg = longMsg;
525            this.stack = stack;
526        }
527
528        final long time;
529        final String shortMsg;
530        final String longMsg;
531        final String stack;
532    }
533
534    /**
535     * Set of applications that we consider to be bad, and will reject
536     * incoming broadcasts from (which the user has no control over).
537     * Processes are added to this set when they have crashed twice within
538     * a minimum amount of time; they are removed from it when they are
539     * later restarted (hopefully due to some user action).  The value is the
540     * time it was added to the list.
541     */
542    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
543
544    /**
545     * All of the processes we currently have running organized by pid.
546     * The keys are the pid running the application.
547     *
548     * <p>NOTE: This object is protected by its own lock, NOT the global
549     * activity manager lock!
550     */
551    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
552
553    /**
554     * All of the processes that have been forced to be foreground.  The key
555     * is the pid of the caller who requested it (we hold a death
556     * link on it).
557     */
558    abstract class ForegroundToken implements IBinder.DeathRecipient {
559        int pid;
560        IBinder token;
561    }
562    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
563
564    /**
565     * List of records for processes that someone had tried to start before the
566     * system was ready.  We don't start them at that point, but ensure they
567     * are started by the time booting is complete.
568     */
569    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
570
571    /**
572     * List of persistent applications that are in the process
573     * of being started.
574     */
575    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * Processes that are being forcibly torn down.
579     */
580    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
581
582    /**
583     * List of running applications, sorted by recent usage.
584     * The first entry in the list is the least recently used.
585     */
586    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Where in mLruProcesses that the processes hosting activities start.
590     */
591    int mLruProcessActivityStart = 0;
592
593    /**
594     * Where in mLruProcesses that the processes hosting services start.
595     * This is after (lower index) than mLruProcessesActivityStart.
596     */
597    int mLruProcessServiceStart = 0;
598
599    /**
600     * List of processes that should gc as soon as things are idle.
601     */
602    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
603
604    /**
605     * Processes we want to collect PSS data from.
606     */
607    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
608
609    /**
610     * Last time we requested PSS data of all processes.
611     */
612    long mLastFullPssTime = SystemClock.uptimeMillis();
613
614    /**
615     * If set, the next time we collect PSS data we should do a full collection
616     * with data from native processes and the kernel.
617     */
618    boolean mFullPssPending = false;
619
620    /**
621     * This is the process holding what we currently consider to be
622     * the "home" activity.
623     */
624    ProcessRecord mHomeProcess;
625
626    /**
627     * This is the process holding the activity the user last visited that
628     * is in a different process from the one they are currently in.
629     */
630    ProcessRecord mPreviousProcess;
631
632    /**
633     * The time at which the previous process was last visible.
634     */
635    long mPreviousProcessVisibleTime;
636
637    /**
638     * Which uses have been started, so are allowed to run code.
639     */
640    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
641
642    /**
643     * LRU list of history of current users.  Most recently current is at the end.
644     */
645    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
646
647    /**
648     * Constant array of the users that are currently started.
649     */
650    int[] mStartedUserArray = new int[] { 0 };
651
652    /**
653     * Registered observers of the user switching mechanics.
654     */
655    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
656            = new RemoteCallbackList<IUserSwitchObserver>();
657
658    /**
659     * Currently active user switch.
660     */
661    Object mCurUserSwitchCallback;
662
663    /**
664     * Packages that the user has asked to have run in screen size
665     * compatibility mode instead of filling the screen.
666     */
667    final CompatModePackages mCompatModePackages;
668
669    /**
670     * Set of IntentSenderRecord objects that are currently active.
671     */
672    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
673            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
674
675    /**
676     * Fingerprints (hashCode()) of stack traces that we've
677     * already logged DropBox entries for.  Guarded by itself.  If
678     * something (rogue user app) forces this over
679     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
680     */
681    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
682    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
683
684    /**
685     * Strict Mode background batched logging state.
686     *
687     * The string buffer is guarded by itself, and its lock is also
688     * used to determine if another batched write is already
689     * in-flight.
690     */
691    private final StringBuilder mStrictModeBuffer = new StringBuilder();
692
693    /**
694     * Keeps track of all IIntentReceivers that have been registered for
695     * broadcasts.  Hash keys are the receiver IBinder, hash value is
696     * a ReceiverList.
697     */
698    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
699            new HashMap<IBinder, ReceiverList>();
700
701    /**
702     * Resolver for broadcast intents to registered receivers.
703     * Holds BroadcastFilter (subclass of IntentFilter).
704     */
705    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
706            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
707        @Override
708        protected boolean allowFilterResult(
709                BroadcastFilter filter, List<BroadcastFilter> dest) {
710            IBinder target = filter.receiverList.receiver.asBinder();
711            for (int i=dest.size()-1; i>=0; i--) {
712                if (dest.get(i).receiverList.receiver.asBinder() == target) {
713                    return false;
714                }
715            }
716            return true;
717        }
718
719        @Override
720        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
721            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
722                    || userId == filter.owningUserId) {
723                return super.newResult(filter, match, userId);
724            }
725            return null;
726        }
727
728        @Override
729        protected BroadcastFilter[] newArray(int size) {
730            return new BroadcastFilter[size];
731        }
732
733        @Override
734        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
735            return packageName.equals(filter.packageName);
736        }
737    };
738
739    /**
740     * State of all active sticky broadcasts per user.  Keys are the action of the
741     * sticky Intent, values are an ArrayList of all broadcasted intents with
742     * that action (which should usually be one).  The SparseArray is keyed
743     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
744     * for stickies that are sent to all users.
745     */
746    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
747            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
748
749    final ActiveServices mServices;
750
751    /**
752     * Backup/restore process management
753     */
754    String mBackupAppName = null;
755    BackupRecord mBackupTarget = null;
756
757    final ProviderMap mProviderMap;
758
759    /**
760     * List of content providers who have clients waiting for them.  The
761     * application is currently being launched and the provider will be
762     * removed from this list once it is published.
763     */
764    final ArrayList<ContentProviderRecord> mLaunchingProviders
765            = new ArrayList<ContentProviderRecord>();
766
767    /**
768     * File storing persisted {@link #mGrantedUriPermissions}.
769     */
770    private final AtomicFile mGrantFile;
771
772    /** XML constants used in {@link #mGrantFile} */
773    private static final String TAG_URI_GRANTS = "uri-grants";
774    private static final String TAG_URI_GRANT = "uri-grant";
775    private static final String ATTR_USER_HANDLE = "userHandle";
776    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
777    private static final String ATTR_TARGET_USER_ID = "targetUserId";
778    private static final String ATTR_SOURCE_PKG = "sourcePkg";
779    private static final String ATTR_TARGET_PKG = "targetPkg";
780    private static final String ATTR_URI = "uri";
781    private static final String ATTR_MODE_FLAGS = "modeFlags";
782    private static final String ATTR_CREATED_TIME = "createdTime";
783    private static final String ATTR_PREFIX = "prefix";
784
785    /**
786     * Global set of specific {@link Uri} permissions that have been granted.
787     * This optimized lookup structure maps from {@link UriPermission#targetUid}
788     * to {@link UriPermission#uri} to {@link UriPermission}.
789     */
790    @GuardedBy("this")
791    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
792            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
793
794    public static class GrantUri {
795        public final int sourceUserId;
796        public final Uri uri;
797        public boolean prefix;
798
799        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
800            this.sourceUserId = sourceUserId;
801            this.uri = uri;
802            this.prefix = prefix;
803        }
804
805        @Override
806        public int hashCode() {
807            int hashCode = 1;
808            hashCode = 31 * hashCode + sourceUserId;
809            hashCode = 31 * hashCode + uri.hashCode();
810            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
811            return hashCode;
812        }
813
814        @Override
815        public boolean equals(Object o) {
816            if (o instanceof GrantUri) {
817                GrantUri other = (GrantUri) o;
818                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
819                        && prefix == other.prefix;
820            }
821            return false;
822        }
823
824        @Override
825        public String toString() {
826            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
827            if (prefix) result += " [prefix]";
828            return result;
829        }
830
831        public String toSafeString() {
832            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
833            if (prefix) result += " [prefix]";
834            return result;
835        }
836
837        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
838            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
839                    ContentProvider.getUriWithoutUserId(uri), false);
840        }
841    }
842
843    CoreSettingsObserver mCoreSettingsObserver;
844
845    /**
846     * Thread-local storage used to carry caller permissions over through
847     * indirect content-provider access.
848     */
849    private class Identity {
850        public final IBinder token;
851        public final int pid;
852        public final int uid;
853
854        Identity(IBinder _token, int _pid, int _uid) {
855            token = _token;
856            pid = _pid;
857            uid = _uid;
858        }
859    }
860
861    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
862
863    /**
864     * All information we have collected about the runtime performance of
865     * any user id that can impact battery performance.
866     */
867    final BatteryStatsService mBatteryStatsService;
868
869    /**
870     * Information about component usage
871     */
872    UsageStatsManagerInternal mUsageStatsService;
873
874    /**
875     * Information about and control over application operations
876     */
877    final AppOpsService mAppOpsService;
878
879    /**
880     * Save recent tasks information across reboots.
881     */
882    final TaskPersister mTaskPersister;
883
884    /**
885     * Current configuration information.  HistoryRecord objects are given
886     * a reference to this object to indicate which configuration they are
887     * currently running in, so this object must be kept immutable.
888     */
889    Configuration mConfiguration = new Configuration();
890
891    /**
892     * Current sequencing integer of the configuration, for skipping old
893     * configurations.
894     */
895    int mConfigurationSeq = 0;
896
897    /**
898     * Hardware-reported OpenGLES version.
899     */
900    final int GL_ES_VERSION;
901
902    /**
903     * List of initialization arguments to pass to all processes when binding applications to them.
904     * For example, references to the commonly used services.
905     */
906    HashMap<String, IBinder> mAppBindArgs;
907
908    /**
909     * Temporary to avoid allocations.  Protected by main lock.
910     */
911    final StringBuilder mStringBuilder = new StringBuilder(256);
912
913    /**
914     * Used to control how we initialize the service.
915     */
916    ComponentName mTopComponent;
917    String mTopAction = Intent.ACTION_MAIN;
918    String mTopData;
919    boolean mProcessesReady = false;
920    boolean mSystemReady = false;
921    boolean mBooting = false;
922    boolean mCallFinishBooting = false;
923    boolean mBootAnimationComplete = false;
924    boolean mWaitingUpdate = false;
925    boolean mDidUpdate = false;
926    boolean mOnBattery = false;
927    boolean mLaunchWarningShown = false;
928
929    Context mContext;
930
931    int mFactoryTest;
932
933    boolean mCheckedForSetup;
934
935    /**
936     * The time at which we will allow normal application switches again,
937     * after a call to {@link #stopAppSwitches()}.
938     */
939    long mAppSwitchesAllowedTime;
940
941    /**
942     * This is set to true after the first switch after mAppSwitchesAllowedTime
943     * is set; any switches after that will clear the time.
944     */
945    boolean mDidAppSwitch;
946
947    /**
948     * Last time (in realtime) at which we checked for power usage.
949     */
950    long mLastPowerCheckRealtime;
951
952    /**
953     * Last time (in uptime) at which we checked for power usage.
954     */
955    long mLastPowerCheckUptime;
956
957    /**
958     * Set while we are wanting to sleep, to prevent any
959     * activities from being started/resumed.
960     */
961    private boolean mSleeping = false;
962
963    /**
964     * Set while we are running a voice interaction.  This overrides
965     * sleeping while it is active.
966     */
967    private boolean mRunningVoice = false;
968
969    /**
970     * State of external calls telling us if the device is awake or asleep.
971     */
972    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
973
974    static final int LOCK_SCREEN_HIDDEN = 0;
975    static final int LOCK_SCREEN_LEAVING = 1;
976    static final int LOCK_SCREEN_SHOWN = 2;
977    /**
978     * State of external call telling us if the lock screen is shown.
979     */
980    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
981
982    /**
983     * Set if we are shutting down the system, similar to sleeping.
984     */
985    boolean mShuttingDown = false;
986
987    /**
988     * Current sequence id for oom_adj computation traversal.
989     */
990    int mAdjSeq = 0;
991
992    /**
993     * Current sequence id for process LRU updating.
994     */
995    int mLruSeq = 0;
996
997    /**
998     * Keep track of the non-cached/empty process we last found, to help
999     * determine how to distribute cached/empty processes next time.
1000     */
1001    int mNumNonCachedProcs = 0;
1002
1003    /**
1004     * Keep track of the number of cached hidden procs, to balance oom adj
1005     * distribution between those and empty procs.
1006     */
1007    int mNumCachedHiddenProcs = 0;
1008
1009    /**
1010     * Keep track of the number of service processes we last found, to
1011     * determine on the next iteration which should be B services.
1012     */
1013    int mNumServiceProcs = 0;
1014    int mNewNumAServiceProcs = 0;
1015    int mNewNumServiceProcs = 0;
1016
1017    /**
1018     * Allow the current computed overall memory level of the system to go down?
1019     * This is set to false when we are killing processes for reasons other than
1020     * memory management, so that the now smaller process list will not be taken as
1021     * an indication that memory is tighter.
1022     */
1023    boolean mAllowLowerMemLevel = false;
1024
1025    /**
1026     * The last computed memory level, for holding when we are in a state that
1027     * processes are going away for other reasons.
1028     */
1029    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1030
1031    /**
1032     * The last total number of process we have, to determine if changes actually look
1033     * like a shrinking number of process due to lower RAM.
1034     */
1035    int mLastNumProcesses;
1036
1037    /**
1038     * The uptime of the last time we performed idle maintenance.
1039     */
1040    long mLastIdleTime = SystemClock.uptimeMillis();
1041
1042    /**
1043     * Total time spent with RAM that has been added in the past since the last idle time.
1044     */
1045    long mLowRamTimeSinceLastIdle = 0;
1046
1047    /**
1048     * If RAM is currently low, when that horrible situation started.
1049     */
1050    long mLowRamStartTime = 0;
1051
1052    /**
1053     * For reporting to battery stats the current top application.
1054     */
1055    private String mCurResumedPackage = null;
1056    private int mCurResumedUid = -1;
1057
1058    /**
1059     * For reporting to battery stats the apps currently running foreground
1060     * service.  The ProcessMap is package/uid tuples; each of these contain
1061     * an array of the currently foreground processes.
1062     */
1063    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1064            = new ProcessMap<ArrayList<ProcessRecord>>();
1065
1066    /**
1067     * This is set if we had to do a delayed dexopt of an app before launching
1068     * it, to increase the ANR timeouts in that case.
1069     */
1070    boolean mDidDexOpt;
1071
1072    /**
1073     * Set if the systemServer made a call to enterSafeMode.
1074     */
1075    boolean mSafeMode;
1076
1077    String mDebugApp = null;
1078    boolean mWaitForDebugger = false;
1079    boolean mDebugTransient = false;
1080    String mOrigDebugApp = null;
1081    boolean mOrigWaitForDebugger = false;
1082    boolean mAlwaysFinishActivities = false;
1083    IActivityController mController = null;
1084    String mProfileApp = null;
1085    ProcessRecord mProfileProc = null;
1086    String mProfileFile;
1087    ParcelFileDescriptor mProfileFd;
1088    int mSamplingInterval = 0;
1089    boolean mAutoStopProfiler = false;
1090    int mProfileType = 0;
1091    String mOpenGlTraceApp = null;
1092
1093    static class ProcessChangeItem {
1094        static final int CHANGE_ACTIVITIES = 1<<0;
1095        static final int CHANGE_PROCESS_STATE = 1<<1;
1096        int changes;
1097        int uid;
1098        int pid;
1099        int processState;
1100        boolean foregroundActivities;
1101    }
1102
1103    final RemoteCallbackList<IProcessObserver> mProcessObservers
1104            = new RemoteCallbackList<IProcessObserver>();
1105    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1106
1107    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1108            = new ArrayList<ProcessChangeItem>();
1109    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1110            = new ArrayList<ProcessChangeItem>();
1111
1112    /**
1113     * Runtime CPU use collection thread.  This object's lock is used to
1114     * perform synchronization with the thread (notifying it to run).
1115     */
1116    final Thread mProcessCpuThread;
1117
1118    /**
1119     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1120     * Must acquire this object's lock when accessing it.
1121     * NOTE: this lock will be held while doing long operations (trawling
1122     * through all processes in /proc), so it should never be acquired by
1123     * any critical paths such as when holding the main activity manager lock.
1124     */
1125    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1126            MONITOR_THREAD_CPU_USAGE);
1127    final AtomicLong mLastCpuTime = new AtomicLong(0);
1128    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1129
1130    long mLastWriteTime = 0;
1131
1132    /**
1133     * Used to retain an update lock when the foreground activity is in
1134     * immersive mode.
1135     */
1136    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1137
1138    /**
1139     * Set to true after the system has finished booting.
1140     */
1141    boolean mBooted = false;
1142
1143    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1144    int mProcessLimitOverride = -1;
1145
1146    WindowManagerService mWindowManager;
1147
1148    final ActivityThread mSystemThread;
1149
1150    // Holds the current foreground user's id
1151    int mCurrentUserId = 0;
1152    // Holds the target user's id during a user switch
1153    int mTargetUserId = UserHandle.USER_NULL;
1154    // If there are multiple profiles for the current user, their ids are here
1155    // Currently only the primary user can have managed profiles
1156    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1157
1158    /**
1159     * Mapping from each known user ID to the profile group ID it is associated with.
1160     */
1161    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1162
1163    private UserManagerService mUserManager;
1164
1165    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1166        final ProcessRecord mApp;
1167        final int mPid;
1168        final IApplicationThread mAppThread;
1169
1170        AppDeathRecipient(ProcessRecord app, int pid,
1171                IApplicationThread thread) {
1172            if (localLOGV) Slog.v(
1173                TAG, "New death recipient " + this
1174                + " for thread " + thread.asBinder());
1175            mApp = app;
1176            mPid = pid;
1177            mAppThread = thread;
1178        }
1179
1180        @Override
1181        public void binderDied() {
1182            if (localLOGV) Slog.v(
1183                TAG, "Death received in " + this
1184                + " for thread " + mAppThread.asBinder());
1185            synchronized(ActivityManagerService.this) {
1186                appDiedLocked(mApp, mPid, mAppThread);
1187            }
1188        }
1189    }
1190
1191    static final int SHOW_ERROR_MSG = 1;
1192    static final int SHOW_NOT_RESPONDING_MSG = 2;
1193    static final int SHOW_FACTORY_ERROR_MSG = 3;
1194    static final int UPDATE_CONFIGURATION_MSG = 4;
1195    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1196    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1197    static final int SERVICE_TIMEOUT_MSG = 12;
1198    static final int UPDATE_TIME_ZONE = 13;
1199    static final int SHOW_UID_ERROR_MSG = 14;
1200    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1201    static final int PROC_START_TIMEOUT_MSG = 20;
1202    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1203    static final int KILL_APPLICATION_MSG = 22;
1204    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1205    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1206    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1207    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1208    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1209    static final int CLEAR_DNS_CACHE_MSG = 28;
1210    static final int UPDATE_HTTP_PROXY_MSG = 29;
1211    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1212    static final int DISPATCH_PROCESSES_CHANGED = 31;
1213    static final int DISPATCH_PROCESS_DIED = 32;
1214    static final int REPORT_MEM_USAGE_MSG = 33;
1215    static final int REPORT_USER_SWITCH_MSG = 34;
1216    static final int CONTINUE_USER_SWITCH_MSG = 35;
1217    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1218    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1219    static final int PERSIST_URI_GRANTS_MSG = 38;
1220    static final int REQUEST_ALL_PSS_MSG = 39;
1221    static final int START_PROFILES_MSG = 40;
1222    static final int UPDATE_TIME = 41;
1223    static final int SYSTEM_USER_START_MSG = 42;
1224    static final int SYSTEM_USER_CURRENT_MSG = 43;
1225    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1226    static final int FINISH_BOOTING_MSG = 45;
1227    static final int START_USER_SWITCH_MSG = 46;
1228    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1229    static final int DISMISS_DIALOG_MSG = 48;
1230    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1231
1232    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1233    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1234    static final int FIRST_COMPAT_MODE_MSG = 300;
1235    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1236
1237    CompatModeDialog mCompatModeDialog;
1238    long mLastMemUsageReportTime = 0;
1239
1240    /**
1241     * Flag whether the current user is a "monkey", i.e. whether
1242     * the UI is driven by a UI automation tool.
1243     */
1244    private boolean mUserIsMonkey;
1245
1246    /** Flag whether the device has a Recents UI */
1247    boolean mHasRecents;
1248
1249    /** The dimensions of the thumbnails in the Recents UI. */
1250    int mThumbnailWidth;
1251    int mThumbnailHeight;
1252
1253    final ServiceThread mHandlerThread;
1254    final MainHandler mHandler;
1255
1256    final class MainHandler extends Handler {
1257        public MainHandler(Looper looper) {
1258            super(looper, null, true);
1259        }
1260
1261        @Override
1262        public void handleMessage(Message msg) {
1263            switch (msg.what) {
1264            case SHOW_ERROR_MSG: {
1265                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1266                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1267                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord)data.get("app");
1270                    AppErrorResult res = (AppErrorResult) data.get("result");
1271                    if (proc != null && proc.crashDialog != null) {
1272                        Slog.e(TAG, "App already has crash dialog: " + proc);
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                        return;
1277                    }
1278                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1279                            >= Process.FIRST_APPLICATION_UID
1280                            && proc.pid != MY_PID);
1281                    for (int userId : mCurrentProfileIds) {
1282                        isBackground &= (proc.userId != userId);
1283                    }
1284                    if (isBackground && !showBackground) {
1285                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1286                        if (res != null) {
1287                            res.set(0);
1288                        }
1289                        return;
1290                    }
1291                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1292                        Dialog d = new AppErrorDialog(mContext,
1293                                ActivityManagerService.this, res, proc);
1294                        d.show();
1295                        proc.crashDialog = d;
1296                    } else {
1297                        // The device is asleep, so just pretend that the user
1298                        // saw a crash dialog and hit "force quit".
1299                        if (res != null) {
1300                            res.set(0);
1301                        }
1302                    }
1303                }
1304
1305                ensureBootCompleted();
1306            } break;
1307            case SHOW_NOT_RESPONDING_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1310                    ProcessRecord proc = (ProcessRecord)data.get("app");
1311                    if (proc != null && proc.anrDialog != null) {
1312                        Slog.e(TAG, "App already has anr dialog: " + proc);
1313                        return;
1314                    }
1315
1316                    Intent intent = new Intent("android.intent.action.ANR");
1317                    if (!mProcessesReady) {
1318                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1319                                | Intent.FLAG_RECEIVER_FOREGROUND);
1320                    }
1321                    broadcastIntentLocked(null, null, intent,
1322                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1323                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1324
1325                    if (mShowDialogs) {
1326                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1327                                mContext, proc, (ActivityRecord)data.get("activity"),
1328                                msg.arg1 != 0);
1329                        d.show();
1330                        proc.anrDialog = d;
1331                    } else {
1332                        // Just kill the app if there is no dialog to be shown.
1333                        killAppAtUsersRequest(proc, null);
1334                    }
1335                }
1336
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1340                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord proc = (ProcessRecord) data.get("app");
1343                    if (proc == null) {
1344                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1345                        break;
1346                    }
1347                    if (proc.crashDialog != null) {
1348                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1349                        return;
1350                    }
1351                    AppErrorResult res = (AppErrorResult) data.get("result");
1352                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1353                        Dialog d = new StrictModeViolationDialog(mContext,
1354                                ActivityManagerService.this, res, proc);
1355                        d.show();
1356                        proc.crashDialog = d;
1357                    } else {
1358                        // The device is asleep, so just pretend that the user
1359                        // saw a crash dialog and hit "force quit".
1360                        res.set(0);
1361                    }
1362                }
1363                ensureBootCompleted();
1364            } break;
1365            case SHOW_FACTORY_ERROR_MSG: {
1366                Dialog d = new FactoryErrorDialog(
1367                    mContext, msg.getData().getCharSequence("msg"));
1368                d.show();
1369                ensureBootCompleted();
1370            } break;
1371            case UPDATE_CONFIGURATION_MSG: {
1372                final ContentResolver resolver = mContext.getContentResolver();
1373                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1374            } break;
1375            case GC_BACKGROUND_PROCESSES_MSG: {
1376                synchronized (ActivityManagerService.this) {
1377                    performAppGcsIfAppropriateLocked();
1378                }
1379            } break;
1380            case WAIT_FOR_DEBUGGER_MSG: {
1381                synchronized (ActivityManagerService.this) {
1382                    ProcessRecord app = (ProcessRecord)msg.obj;
1383                    if (msg.arg1 != 0) {
1384                        if (!app.waitedForDebugger) {
1385                            Dialog d = new AppWaitingForDebuggerDialog(
1386                                    ActivityManagerService.this,
1387                                    mContext, app);
1388                            app.waitDialog = d;
1389                            app.waitedForDebugger = true;
1390                            d.show();
1391                        }
1392                    } else {
1393                        if (app.waitDialog != null) {
1394                            app.waitDialog.dismiss();
1395                            app.waitDialog = null;
1396                        }
1397                    }
1398                }
1399            } break;
1400            case SERVICE_TIMEOUT_MSG: {
1401                if (mDidDexOpt) {
1402                    mDidDexOpt = false;
1403                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1404                    nmsg.obj = msg.obj;
1405                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1406                    return;
1407                }
1408                mServices.serviceTimeout((ProcessRecord)msg.obj);
1409            } break;
1410            case UPDATE_TIME_ZONE: {
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.updateTimeZone();
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case CLEAR_DNS_CACHE_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1427                        ProcessRecord r = mLruProcesses.get(i);
1428                        if (r.thread != null) {
1429                            try {
1430                                r.thread.clearDnsCache();
1431                            } catch (RemoteException ex) {
1432                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case UPDATE_HTTP_PROXY_MSG: {
1439                ProxyInfo proxy = (ProxyInfo)msg.obj;
1440                String host = "";
1441                String port = "";
1442                String exclList = "";
1443                Uri pacFileUrl = Uri.EMPTY;
1444                if (proxy != null) {
1445                    host = proxy.getHost();
1446                    port = Integer.toString(proxy.getPort());
1447                    exclList = proxy.getExclusionListAsString();
1448                    pacFileUrl = proxy.getPacFileUrl();
1449                }
1450                synchronized (ActivityManagerService.this) {
1451                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1452                        ProcessRecord r = mLruProcesses.get(i);
1453                        if (r.thread != null) {
1454                            try {
1455                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1456                            } catch (RemoteException ex) {
1457                                Slog.w(TAG, "Failed to update http proxy for: " +
1458                                        r.info.processName);
1459                            }
1460                        }
1461                    }
1462                }
1463            } break;
1464            case SHOW_UID_ERROR_MSG: {
1465                if (mShowDialogs) {
1466                    AlertDialog d = new BaseErrorDialog(mContext);
1467                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1468                    d.setCancelable(false);
1469                    d.setTitle(mContext.getText(R.string.android_system_label));
1470                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1471                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1472                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1473                    d.show();
1474                }
1475            } break;
1476            case SHOW_FINGERPRINT_ERROR_MSG: {
1477                if (mShowDialogs) {
1478                    AlertDialog d = new BaseErrorDialog(mContext);
1479                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1480                    d.setCancelable(false);
1481                    d.setTitle(mContext.getText(R.string.android_system_label));
1482                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1483                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1484                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1485                    d.show();
1486                }
1487            } break;
1488            case PROC_START_TIMEOUT_MSG: {
1489                if (mDidDexOpt) {
1490                    mDidDexOpt = false;
1491                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1492                    nmsg.obj = msg.obj;
1493                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1494                    return;
1495                }
1496                ProcessRecord app = (ProcessRecord)msg.obj;
1497                synchronized (ActivityManagerService.this) {
1498                    processStartTimedOutLocked(app);
1499                }
1500            } break;
1501            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1504                }
1505            } break;
1506            case KILL_APPLICATION_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    int appid = msg.arg1;
1509                    boolean restart = (msg.arg2 == 1);
1510                    Bundle bundle = (Bundle)msg.obj;
1511                    String pkg = bundle.getString("pkg");
1512                    String reason = bundle.getString("reason");
1513                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1514                            false, UserHandle.USER_ALL, reason);
1515                }
1516            } break;
1517            case FINALIZE_PENDING_INTENT_MSG: {
1518                ((PendingIntentRecord)msg.obj).completeFinalize();
1519            } break;
1520            case POST_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525
1526                ActivityRecord root = (ActivityRecord)msg.obj;
1527                ProcessRecord process = root.app;
1528                if (process == null) {
1529                    return;
1530                }
1531
1532                try {
1533                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1534                    String text = mContext.getString(R.string.heavy_weight_notification,
1535                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1536                    Notification notification = new Notification();
1537                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1538                    notification.when = 0;
1539                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1540                    notification.tickerText = text;
1541                    notification.defaults = 0; // please be quiet
1542                    notification.sound = null;
1543                    notification.vibrate = null;
1544                    notification.color = mContext.getResources().getColor(
1545                            com.android.internal.R.color.system_notification_accent_color);
1546                    notification.setLatestEventInfo(context, text,
1547                            mContext.getText(R.string.heavy_weight_notification_detail),
1548                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1549                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1550                                    new UserHandle(root.userId)));
1551
1552                    try {
1553                        int[] outId = new int[1];
1554                        inm.enqueueNotificationWithTag("android", "android", null,
1555                                R.string.heavy_weight_notification,
1556                                notification, outId, root.userId);
1557                    } catch (RuntimeException e) {
1558                        Slog.w(ActivityManagerService.TAG,
1559                                "Error showing notification for heavy-weight app", e);
1560                    } catch (RemoteException e) {
1561                    }
1562                } catch (NameNotFoundException e) {
1563                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1564                }
1565            } break;
1566            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1567                INotificationManager inm = NotificationManager.getService();
1568                if (inm == null) {
1569                    return;
1570                }
1571                try {
1572                    inm.cancelNotificationWithTag("android", null,
1573                            R.string.heavy_weight_notification,  msg.arg1);
1574                } catch (RuntimeException e) {
1575                    Slog.w(ActivityManagerService.TAG,
1576                            "Error canceling notification for service", e);
1577                } catch (RemoteException e) {
1578                }
1579            } break;
1580            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1581                synchronized (ActivityManagerService.this) {
1582                    checkExcessivePowerUsageLocked(true);
1583                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1584                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1585                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1586                }
1587            } break;
1588            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1589                synchronized (ActivityManagerService.this) {
1590                    ActivityRecord ar = (ActivityRecord)msg.obj;
1591                    if (mCompatModeDialog != null) {
1592                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1593                                ar.info.applicationInfo.packageName)) {
1594                            return;
1595                        }
1596                        mCompatModeDialog.dismiss();
1597                        mCompatModeDialog = null;
1598                    }
1599                    if (ar != null && false) {
1600                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1601                                ar.packageName)) {
1602                            int mode = mCompatModePackages.computeCompatModeLocked(
1603                                    ar.info.applicationInfo);
1604                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1605                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1606                                mCompatModeDialog = new CompatModeDialog(
1607                                        ActivityManagerService.this, mContext,
1608                                        ar.info.applicationInfo);
1609                                mCompatModeDialog.show();
1610                            }
1611                        }
1612                    }
1613                }
1614                break;
1615            }
1616            case DISPATCH_PROCESSES_CHANGED: {
1617                dispatchProcessesChanged();
1618                break;
1619            }
1620            case DISPATCH_PROCESS_DIED: {
1621                final int pid = msg.arg1;
1622                final int uid = msg.arg2;
1623                dispatchProcessDied(pid, uid);
1624                break;
1625            }
1626            case REPORT_MEM_USAGE_MSG: {
1627                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1628                Thread thread = new Thread() {
1629                    @Override public void run() {
1630                        reportMemUsage(memInfos);
1631                    }
1632                };
1633                thread.start();
1634                break;
1635            }
1636            case START_USER_SWITCH_MSG: {
1637                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1638                break;
1639            }
1640            case REPORT_USER_SWITCH_MSG: {
1641                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1642                break;
1643            }
1644            case CONTINUE_USER_SWITCH_MSG: {
1645                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1646                break;
1647            }
1648            case USER_SWITCH_TIMEOUT_MSG: {
1649                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1650                break;
1651            }
1652            case IMMERSIVE_MODE_LOCK_MSG: {
1653                final boolean nextState = (msg.arg1 != 0);
1654                if (mUpdateLock.isHeld() != nextState) {
1655                    if (DEBUG_IMMERSIVE) {
1656                        final ActivityRecord r = (ActivityRecord) msg.obj;
1657                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1658                    }
1659                    if (nextState) {
1660                        mUpdateLock.acquire();
1661                    } else {
1662                        mUpdateLock.release();
1663                    }
1664                }
1665                break;
1666            }
1667            case PERSIST_URI_GRANTS_MSG: {
1668                writeGrantedUriPermissions();
1669                break;
1670            }
1671            case REQUEST_ALL_PSS_MSG: {
1672                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1673                break;
1674            }
1675            case START_PROFILES_MSG: {
1676                synchronized (ActivityManagerService.this) {
1677                    startProfilesLocked();
1678                }
1679                break;
1680            }
1681            case UPDATE_TIME: {
1682                synchronized (ActivityManagerService.this) {
1683                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1684                        ProcessRecord r = mLruProcesses.get(i);
1685                        if (r.thread != null) {
1686                            try {
1687                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1688                            } catch (RemoteException ex) {
1689                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case SYSTEM_USER_START_MSG: {
1697                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1698                        Integer.toString(msg.arg1), msg.arg1);
1699                mSystemServiceManager.startUser(msg.arg1);
1700                break;
1701            }
1702            case SYSTEM_USER_CURRENT_MSG: {
1703                mBatteryStatsService.noteEvent(
1704                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1705                        Integer.toString(msg.arg2), msg.arg2);
1706                mBatteryStatsService.noteEvent(
1707                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1708                        Integer.toString(msg.arg1), msg.arg1);
1709                mSystemServiceManager.switchUser(msg.arg1);
1710                break;
1711            }
1712            case ENTER_ANIMATION_COMPLETE_MSG: {
1713                synchronized (ActivityManagerService.this) {
1714                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1715                    if (r != null && r.app != null && r.app.thread != null) {
1716                        try {
1717                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1718                        } catch (RemoteException e) {
1719                        }
1720                    }
1721                }
1722                break;
1723            }
1724            case FINISH_BOOTING_MSG: {
1725                if (msg.arg1 != 0) {
1726                    finishBooting();
1727                }
1728                if (msg.arg2 != 0) {
1729                    enableScreenAfterBoot();
1730                }
1731                break;
1732            }
1733            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1734                try {
1735                    Locale l = (Locale) msg.obj;
1736                    IBinder service = ServiceManager.getService("mount");
1737                    IMountService mountService = IMountService.Stub.asInterface(service);
1738                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1739                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1740                } catch (RemoteException e) {
1741                    Log.e(TAG, "Error storing locale for decryption UI", e);
1742                }
1743                break;
1744            }
1745            case DISMISS_DIALOG_MSG: {
1746                final Dialog d = (Dialog) msg.obj;
1747                d.dismiss();
1748                break;
1749            }
1750            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1751                synchronized (ActivityManagerService.this) {
1752                    int i = mTaskStackListeners.beginBroadcast();
1753                    while (i > 0) {
1754                        i--;
1755                        try {
1756                            // Make a one-way callback to the listener
1757                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1758                        } catch (RemoteException e){
1759                            // Handled by the RemoteCallbackList
1760                        }
1761                    }
1762                    mTaskStackListeners.finishBroadcast();
1763                }
1764                break;
1765            }
1766            }
1767        }
1768    };
1769
1770    static final int COLLECT_PSS_BG_MSG = 1;
1771
1772    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1773        @Override
1774        public void handleMessage(Message msg) {
1775            switch (msg.what) {
1776            case COLLECT_PSS_BG_MSG: {
1777                long start = SystemClock.uptimeMillis();
1778                MemInfoReader memInfo = null;
1779                synchronized (ActivityManagerService.this) {
1780                    if (mFullPssPending) {
1781                        mFullPssPending = false;
1782                        memInfo = new MemInfoReader();
1783                    }
1784                }
1785                if (memInfo != null) {
1786                    updateCpuStatsNow();
1787                    long nativeTotalPss = 0;
1788                    synchronized (mProcessCpuTracker) {
1789                        final int N = mProcessCpuTracker.countStats();
1790                        for (int j=0; j<N; j++) {
1791                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1792                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1793                                // This is definitely an application process; skip it.
1794                                continue;
1795                            }
1796                            synchronized (mPidsSelfLocked) {
1797                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1798                                    // This is one of our own processes; skip it.
1799                                    continue;
1800                                }
1801                            }
1802                            nativeTotalPss += Debug.getPss(st.pid, null);
1803                        }
1804                    }
1805                    memInfo.readMemInfo();
1806                    synchronized (ActivityManagerService.this) {
1807                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1808                                + (SystemClock.uptimeMillis()-start) + "ms");
1809                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1810                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1811                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1812                    }
1813                }
1814
1815                int i = 0;
1816                int num = 0;
1817                long[] tmp = new long[1];
1818                do {
1819                    ProcessRecord proc;
1820                    int procState;
1821                    int pid;
1822                    synchronized (ActivityManagerService.this) {
1823                        if (i >= mPendingPssProcesses.size()) {
1824                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1825                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1826                            mPendingPssProcesses.clear();
1827                            return;
1828                        }
1829                        proc = mPendingPssProcesses.get(i);
1830                        procState = proc.pssProcState;
1831                        if (proc.thread != null && procState == proc.setProcState) {
1832                            pid = proc.pid;
1833                        } else {
1834                            proc = null;
1835                            pid = 0;
1836                        }
1837                        i++;
1838                    }
1839                    if (proc != null) {
1840                        long pss = Debug.getPss(pid, tmp);
1841                        synchronized (ActivityManagerService.this) {
1842                            if (proc.thread != null && proc.setProcState == procState
1843                                    && proc.pid == pid) {
1844                                num++;
1845                                proc.lastPssTime = SystemClock.uptimeMillis();
1846                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1847                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1848                                        + ": " + pss + " lastPss=" + proc.lastPss
1849                                        + " state=" + ProcessList.makeProcStateString(procState));
1850                                if (proc.initialIdlePss == 0) {
1851                                    proc.initialIdlePss = pss;
1852                                }
1853                                proc.lastPss = pss;
1854                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1855                                    proc.lastCachedPss = pss;
1856                                }
1857                            }
1858                        }
1859                    }
1860                } while (true);
1861            }
1862            }
1863        }
1864    };
1865
1866    public void setSystemProcess() {
1867        try {
1868            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1869            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1870            ServiceManager.addService("meminfo", new MemBinder(this));
1871            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1872            ServiceManager.addService("dbinfo", new DbBinder(this));
1873            if (MONITOR_CPU_USAGE) {
1874                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1875            }
1876            ServiceManager.addService("permission", new PermissionController(this));
1877
1878            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1879                    "android", STOCK_PM_FLAGS);
1880            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1881
1882            synchronized (this) {
1883                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1884                app.persistent = true;
1885                app.pid = MY_PID;
1886                app.maxAdj = ProcessList.SYSTEM_ADJ;
1887                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1888                mProcessNames.put(app.processName, app.uid, app);
1889                synchronized (mPidsSelfLocked) {
1890                    mPidsSelfLocked.put(app.pid, app);
1891                }
1892                updateLruProcessLocked(app, false, null);
1893                updateOomAdjLocked();
1894            }
1895        } catch (PackageManager.NameNotFoundException e) {
1896            throw new RuntimeException(
1897                    "Unable to find android system package", e);
1898        }
1899    }
1900
1901    public void setWindowManager(WindowManagerService wm) {
1902        mWindowManager = wm;
1903        mStackSupervisor.setWindowManager(wm);
1904    }
1905
1906    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1907        mUsageStatsService = usageStatsManager;
1908    }
1909
1910    public void startObservingNativeCrashes() {
1911        final NativeCrashListener ncl = new NativeCrashListener(this);
1912        ncl.start();
1913    }
1914
1915    public IAppOpsService getAppOpsService() {
1916        return mAppOpsService;
1917    }
1918
1919    static class MemBinder extends Binder {
1920        ActivityManagerService mActivityManagerService;
1921        MemBinder(ActivityManagerService activityManagerService) {
1922            mActivityManagerService = activityManagerService;
1923        }
1924
1925        @Override
1926        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1927            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1928                    != PackageManager.PERMISSION_GRANTED) {
1929                pw.println("Permission Denial: can't dump meminfo from from pid="
1930                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1931                        + " without permission " + android.Manifest.permission.DUMP);
1932                return;
1933            }
1934
1935            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1936        }
1937    }
1938
1939    static class GraphicsBinder extends Binder {
1940        ActivityManagerService mActivityManagerService;
1941        GraphicsBinder(ActivityManagerService activityManagerService) {
1942            mActivityManagerService = activityManagerService;
1943        }
1944
1945        @Override
1946        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1947            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1948                    != PackageManager.PERMISSION_GRANTED) {
1949                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1950                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1951                        + " without permission " + android.Manifest.permission.DUMP);
1952                return;
1953            }
1954
1955            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1956        }
1957    }
1958
1959    static class DbBinder extends Binder {
1960        ActivityManagerService mActivityManagerService;
1961        DbBinder(ActivityManagerService activityManagerService) {
1962            mActivityManagerService = activityManagerService;
1963        }
1964
1965        @Override
1966        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1967            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1968                    != PackageManager.PERMISSION_GRANTED) {
1969                pw.println("Permission Denial: can't dump dbinfo from from pid="
1970                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1971                        + " without permission " + android.Manifest.permission.DUMP);
1972                return;
1973            }
1974
1975            mActivityManagerService.dumpDbInfo(fd, pw, args);
1976        }
1977    }
1978
1979    static class CpuBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        CpuBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            synchronized (mActivityManagerService.mProcessCpuTracker) {
1996                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1997                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1998                        SystemClock.uptimeMillis()));
1999            }
2000        }
2001    }
2002
2003    public static final class Lifecycle extends SystemService {
2004        private final ActivityManagerService mService;
2005
2006        public Lifecycle(Context context) {
2007            super(context);
2008            mService = new ActivityManagerService(context);
2009        }
2010
2011        @Override
2012        public void onStart() {
2013            mService.start();
2014        }
2015
2016        public ActivityManagerService getService() {
2017            return mService;
2018        }
2019    }
2020
2021    // Note: This method is invoked on the main thread but may need to attach various
2022    // handlers to other threads.  So take care to be explicit about the looper.
2023    public ActivityManagerService(Context systemContext) {
2024        mContext = systemContext;
2025        mFactoryTest = FactoryTest.getMode();
2026        mSystemThread = ActivityThread.currentActivityThread();
2027
2028        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2029
2030        mHandlerThread = new ServiceThread(TAG,
2031                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2032        mHandlerThread.start();
2033        mHandler = new MainHandler(mHandlerThread.getLooper());
2034
2035        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2036                "foreground", BROADCAST_FG_TIMEOUT, false);
2037        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "background", BROADCAST_BG_TIMEOUT, true);
2039        mBroadcastQueues[0] = mFgBroadcastQueue;
2040        mBroadcastQueues[1] = mBgBroadcastQueue;
2041
2042        mServices = new ActiveServices(this);
2043        mProviderMap = new ProviderMap(this);
2044
2045        // TODO: Move creation of battery stats service outside of activity manager service.
2046        File dataDir = Environment.getDataDirectory();
2047        File systemDir = new File(dataDir, "system");
2048        systemDir.mkdirs();
2049        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2050        mBatteryStatsService.getActiveStatistics().readLocked();
2051        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2052        mOnBattery = DEBUG_POWER ? true
2053                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2054        mBatteryStatsService.getActiveStatistics().setCallback(this);
2055
2056        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2057
2058        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2059
2060        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2061
2062        // User 0 is the first and only user that runs at boot.
2063        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2064        mUserLru.add(Integer.valueOf(0));
2065        updateStartedUserArrayLocked();
2066
2067        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2068            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2069
2070        mConfiguration.setToDefaults();
2071        mConfiguration.setLocale(Locale.getDefault());
2072
2073        mConfigurationSeq = mConfiguration.seq = 1;
2074        mProcessCpuTracker.init();
2075
2076        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2077        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2078        mStackSupervisor = new ActivityStackSupervisor(this);
2079        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2080
2081        mProcessCpuThread = new Thread("CpuTracker") {
2082            @Override
2083            public void run() {
2084                while (true) {
2085                    try {
2086                        try {
2087                            synchronized(this) {
2088                                final long now = SystemClock.uptimeMillis();
2089                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2090                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2091                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2092                                //        + ", write delay=" + nextWriteDelay);
2093                                if (nextWriteDelay < nextCpuDelay) {
2094                                    nextCpuDelay = nextWriteDelay;
2095                                }
2096                                if (nextCpuDelay > 0) {
2097                                    mProcessCpuMutexFree.set(true);
2098                                    this.wait(nextCpuDelay);
2099                                }
2100                            }
2101                        } catch (InterruptedException e) {
2102                        }
2103                        updateCpuStatsNow();
2104                    } catch (Exception e) {
2105                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2106                    }
2107                }
2108            }
2109        };
2110
2111        Watchdog.getInstance().addMonitor(this);
2112        Watchdog.getInstance().addThread(mHandler);
2113    }
2114
2115    public void setSystemServiceManager(SystemServiceManager mgr) {
2116        mSystemServiceManager = mgr;
2117    }
2118
2119    public void setInstaller(Installer installer) {
2120        mInstaller = installer;
2121    }
2122
2123    private void start() {
2124        Process.removeAllProcessGroups();
2125        mProcessCpuThread.start();
2126
2127        mBatteryStatsService.publish(mContext);
2128        mAppOpsService.publish(mContext);
2129        Slog.d("AppOps", "AppOpsService published");
2130        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2131    }
2132
2133    public void initPowerManagement() {
2134        mStackSupervisor.initPowerManagement();
2135        mBatteryStatsService.initPowerManagement();
2136    }
2137
2138    @Override
2139    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2140            throws RemoteException {
2141        if (code == SYSPROPS_TRANSACTION) {
2142            // We need to tell all apps about the system property change.
2143            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2144            synchronized(this) {
2145                final int NP = mProcessNames.getMap().size();
2146                for (int ip=0; ip<NP; ip++) {
2147                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2148                    final int NA = apps.size();
2149                    for (int ia=0; ia<NA; ia++) {
2150                        ProcessRecord app = apps.valueAt(ia);
2151                        if (app.thread != null) {
2152                            procs.add(app.thread.asBinder());
2153                        }
2154                    }
2155                }
2156            }
2157
2158            int N = procs.size();
2159            for (int i=0; i<N; i++) {
2160                Parcel data2 = Parcel.obtain();
2161                try {
2162                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2163                } catch (RemoteException e) {
2164                }
2165                data2.recycle();
2166            }
2167        }
2168        try {
2169            return super.onTransact(code, data, reply, flags);
2170        } catch (RuntimeException e) {
2171            // The activity manager only throws security exceptions, so let's
2172            // log all others.
2173            if (!(e instanceof SecurityException)) {
2174                Slog.wtf(TAG, "Activity Manager Crash", e);
2175            }
2176            throw e;
2177        }
2178    }
2179
2180    void updateCpuStats() {
2181        final long now = SystemClock.uptimeMillis();
2182        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2183            return;
2184        }
2185        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2186            synchronized (mProcessCpuThread) {
2187                mProcessCpuThread.notify();
2188            }
2189        }
2190    }
2191
2192    void updateCpuStatsNow() {
2193        synchronized (mProcessCpuTracker) {
2194            mProcessCpuMutexFree.set(false);
2195            final long now = SystemClock.uptimeMillis();
2196            boolean haveNewCpuStats = false;
2197
2198            if (MONITOR_CPU_USAGE &&
2199                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2200                mLastCpuTime.set(now);
2201                haveNewCpuStats = true;
2202                mProcessCpuTracker.update();
2203                //Slog.i(TAG, mProcessCpu.printCurrentState());
2204                //Slog.i(TAG, "Total CPU usage: "
2205                //        + mProcessCpu.getTotalCpuPercent() + "%");
2206
2207                // Slog the cpu usage if the property is set.
2208                if ("true".equals(SystemProperties.get("events.cpu"))) {
2209                    int user = mProcessCpuTracker.getLastUserTime();
2210                    int system = mProcessCpuTracker.getLastSystemTime();
2211                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2212                    int irq = mProcessCpuTracker.getLastIrqTime();
2213                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2214                    int idle = mProcessCpuTracker.getLastIdleTime();
2215
2216                    int total = user + system + iowait + irq + softIrq + idle;
2217                    if (total == 0) total = 1;
2218
2219                    EventLog.writeEvent(EventLogTags.CPU,
2220                            ((user+system+iowait+irq+softIrq) * 100) / total,
2221                            (user * 100) / total,
2222                            (system * 100) / total,
2223                            (iowait * 100) / total,
2224                            (irq * 100) / total,
2225                            (softIrq * 100) / total);
2226                }
2227            }
2228
2229            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2230            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2231            synchronized(bstats) {
2232                synchronized(mPidsSelfLocked) {
2233                    if (haveNewCpuStats) {
2234                        if (mOnBattery) {
2235                            int perc = bstats.startAddingCpuLocked();
2236                            int totalUTime = 0;
2237                            int totalSTime = 0;
2238                            final int N = mProcessCpuTracker.countStats();
2239                            for (int i=0; i<N; i++) {
2240                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2241                                if (!st.working) {
2242                                    continue;
2243                                }
2244                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2245                                int otherUTime = (st.rel_utime*perc)/100;
2246                                int otherSTime = (st.rel_stime*perc)/100;
2247                                totalUTime += otherUTime;
2248                                totalSTime += otherSTime;
2249                                if (pr != null) {
2250                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2251                                    if (ps == null || !ps.isActive()) {
2252                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2253                                                pr.info.uid, pr.processName);
2254                                    }
2255                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2256                                            st.rel_stime-otherSTime);
2257                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2258                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2259                                } else {
2260                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2261                                    if (ps == null || !ps.isActive()) {
2262                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2263                                                bstats.mapUid(st.uid), st.name);
2264                                    }
2265                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2266                                            st.rel_stime-otherSTime);
2267                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2268                                }
2269                            }
2270                            bstats.finishAddingCpuLocked(perc, totalUTime,
2271                                    totalSTime, cpuSpeedTimes);
2272                        }
2273                    }
2274                }
2275
2276                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2277                    mLastWriteTime = now;
2278                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2279                }
2280            }
2281        }
2282    }
2283
2284    @Override
2285    public void batteryNeedsCpuUpdate() {
2286        updateCpuStatsNow();
2287    }
2288
2289    @Override
2290    public void batteryPowerChanged(boolean onBattery) {
2291        // When plugging in, update the CPU stats first before changing
2292        // the plug state.
2293        updateCpuStatsNow();
2294        synchronized (this) {
2295            synchronized(mPidsSelfLocked) {
2296                mOnBattery = DEBUG_POWER ? true : onBattery;
2297            }
2298        }
2299    }
2300
2301    /**
2302     * Initialize the application bind args. These are passed to each
2303     * process when the bindApplication() IPC is sent to the process. They're
2304     * lazily setup to make sure the services are running when they're asked for.
2305     */
2306    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2307        if (mAppBindArgs == null) {
2308            mAppBindArgs = new HashMap<>();
2309
2310            // Isolated processes won't get this optimization, so that we don't
2311            // violate the rules about which services they have access to.
2312            if (!isolated) {
2313                // Setup the application init args
2314                mAppBindArgs.put("package", ServiceManager.getService("package"));
2315                mAppBindArgs.put("window", ServiceManager.getService("window"));
2316                mAppBindArgs.put(Context.ALARM_SERVICE,
2317                        ServiceManager.getService(Context.ALARM_SERVICE));
2318            }
2319        }
2320        return mAppBindArgs;
2321    }
2322
2323    final void setFocusedActivityLocked(ActivityRecord r) {
2324        if (mFocusedActivity != r) {
2325            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2326            mFocusedActivity = r;
2327            if (r.task != null && r.task.voiceInteractor != null) {
2328                startRunningVoiceLocked();
2329            } else {
2330                finishRunningVoiceLocked();
2331            }
2332            mStackSupervisor.setFocusedStack(r);
2333            if (r != null) {
2334                mWindowManager.setFocusedApp(r.appToken, true);
2335            }
2336            applyUpdateLockStateLocked(r);
2337        }
2338    }
2339
2340    final void clearFocusedActivity(ActivityRecord r) {
2341        if (mFocusedActivity == r) {
2342            mFocusedActivity = null;
2343        }
2344    }
2345
2346    @Override
2347    public void setFocusedStack(int stackId) {
2348        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2349        synchronized (ActivityManagerService.this) {
2350            ActivityStack stack = mStackSupervisor.getStack(stackId);
2351            if (stack != null) {
2352                ActivityRecord r = stack.topRunningActivityLocked(null);
2353                if (r != null) {
2354                    setFocusedActivityLocked(r);
2355                }
2356            }
2357        }
2358    }
2359
2360    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2361    @Override
2362    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2363        synchronized (ActivityManagerService.this) {
2364            if (listener != null) {
2365                mTaskStackListeners.register(listener);
2366            }
2367        }
2368    }
2369
2370    @Override
2371    public void notifyActivityDrawn(IBinder token) {
2372        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2373        synchronized (this) {
2374            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2375            if (r != null) {
2376                r.task.stack.notifyActivityDrawnLocked(r);
2377            }
2378        }
2379    }
2380
2381    final void applyUpdateLockStateLocked(ActivityRecord r) {
2382        // Modifications to the UpdateLock state are done on our handler, outside
2383        // the activity manager's locks.  The new state is determined based on the
2384        // state *now* of the relevant activity record.  The object is passed to
2385        // the handler solely for logging detail, not to be consulted/modified.
2386        final boolean nextState = r != null && r.immersive;
2387        mHandler.sendMessage(
2388                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2389    }
2390
2391    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2392        Message msg = Message.obtain();
2393        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2394        msg.obj = r.task.askedCompatMode ? null : r;
2395        mHandler.sendMessage(msg);
2396    }
2397
2398    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2399            String what, Object obj, ProcessRecord srcApp) {
2400        app.lastActivityTime = now;
2401
2402        if (app.activities.size() > 0) {
2403            // Don't want to touch dependent processes that are hosting activities.
2404            return index;
2405        }
2406
2407        int lrui = mLruProcesses.lastIndexOf(app);
2408        if (lrui < 0) {
2409            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2410                    + what + " " + obj + " from " + srcApp);
2411            return index;
2412        }
2413
2414        if (lrui >= index) {
2415            // Don't want to cause this to move dependent processes *back* in the
2416            // list as if they were less frequently used.
2417            return index;
2418        }
2419
2420        if (lrui >= mLruProcessActivityStart) {
2421            // Don't want to touch dependent processes that are hosting activities.
2422            return index;
2423        }
2424
2425        mLruProcesses.remove(lrui);
2426        if (index > 0) {
2427            index--;
2428        }
2429        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2430                + " in LRU list: " + app);
2431        mLruProcesses.add(index, app);
2432        return index;
2433    }
2434
2435    final void removeLruProcessLocked(ProcessRecord app) {
2436        int lrui = mLruProcesses.lastIndexOf(app);
2437        if (lrui >= 0) {
2438            if (!app.killed) {
2439                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2440                Process.killProcessQuiet(app.pid);
2441                Process.killProcessGroup(app.info.uid, app.pid);
2442            }
2443            if (lrui <= mLruProcessActivityStart) {
2444                mLruProcessActivityStart--;
2445            }
2446            if (lrui <= mLruProcessServiceStart) {
2447                mLruProcessServiceStart--;
2448            }
2449            mLruProcesses.remove(lrui);
2450        }
2451    }
2452
2453    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2454            ProcessRecord client) {
2455        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2456                || app.treatLikeActivity;
2457        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2458        if (!activityChange && hasActivity) {
2459            // The process has activities, so we are only allowing activity-based adjustments
2460            // to move it.  It should be kept in the front of the list with other
2461            // processes that have activities, and we don't want those to change their
2462            // order except due to activity operations.
2463            return;
2464        }
2465
2466        mLruSeq++;
2467        final long now = SystemClock.uptimeMillis();
2468        app.lastActivityTime = now;
2469
2470        // First a quick reject: if the app is already at the position we will
2471        // put it, then there is nothing to do.
2472        if (hasActivity) {
2473            final int N = mLruProcesses.size();
2474            if (N > 0 && mLruProcesses.get(N-1) == app) {
2475                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2476                return;
2477            }
2478        } else {
2479            if (mLruProcessServiceStart > 0
2480                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2481                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2482                return;
2483            }
2484        }
2485
2486        int lrui = mLruProcesses.lastIndexOf(app);
2487
2488        if (app.persistent && lrui >= 0) {
2489            // We don't care about the position of persistent processes, as long as
2490            // they are in the list.
2491            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2492            return;
2493        }
2494
2495        /* In progress: compute new position first, so we can avoid doing work
2496           if the process is not actually going to move.  Not yet working.
2497        int addIndex;
2498        int nextIndex;
2499        boolean inActivity = false, inService = false;
2500        if (hasActivity) {
2501            // Process has activities, put it at the very tipsy-top.
2502            addIndex = mLruProcesses.size();
2503            nextIndex = mLruProcessServiceStart;
2504            inActivity = true;
2505        } else if (hasService) {
2506            // Process has services, put it at the top of the service list.
2507            addIndex = mLruProcessActivityStart;
2508            nextIndex = mLruProcessServiceStart;
2509            inActivity = true;
2510            inService = true;
2511        } else  {
2512            // Process not otherwise of interest, it goes to the top of the non-service area.
2513            addIndex = mLruProcessServiceStart;
2514            if (client != null) {
2515                int clientIndex = mLruProcesses.lastIndexOf(client);
2516                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2517                        + app);
2518                if (clientIndex >= 0 && addIndex > clientIndex) {
2519                    addIndex = clientIndex;
2520                }
2521            }
2522            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2523        }
2524
2525        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2526                + mLruProcessActivityStart + "): " + app);
2527        */
2528
2529        if (lrui >= 0) {
2530            if (lrui < mLruProcessActivityStart) {
2531                mLruProcessActivityStart--;
2532            }
2533            if (lrui < mLruProcessServiceStart) {
2534                mLruProcessServiceStart--;
2535            }
2536            /*
2537            if (addIndex > lrui) {
2538                addIndex--;
2539            }
2540            if (nextIndex > lrui) {
2541                nextIndex--;
2542            }
2543            */
2544            mLruProcesses.remove(lrui);
2545        }
2546
2547        /*
2548        mLruProcesses.add(addIndex, app);
2549        if (inActivity) {
2550            mLruProcessActivityStart++;
2551        }
2552        if (inService) {
2553            mLruProcessActivityStart++;
2554        }
2555        */
2556
2557        int nextIndex;
2558        if (hasActivity) {
2559            final int N = mLruProcesses.size();
2560            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2561                // Process doesn't have activities, but has clients with
2562                // activities...  move it up, but one below the top (the top
2563                // should always have a real activity).
2564                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2565                mLruProcesses.add(N-1, app);
2566                // To keep it from spamming the LRU list (by making a bunch of clients),
2567                // we will push down any other entries owned by the app.
2568                final int uid = app.info.uid;
2569                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2570                    ProcessRecord subProc = mLruProcesses.get(i);
2571                    if (subProc.info.uid == uid) {
2572                        // We want to push this one down the list.  If the process after
2573                        // it is for the same uid, however, don't do so, because we don't
2574                        // want them internally to be re-ordered.
2575                        if (mLruProcesses.get(i-1).info.uid != uid) {
2576                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2577                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2578                            ProcessRecord tmp = mLruProcesses.get(i);
2579                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2580                            mLruProcesses.set(i-1, tmp);
2581                            i--;
2582                        }
2583                    } else {
2584                        // A gap, we can stop here.
2585                        break;
2586                    }
2587                }
2588            } else {
2589                // Process has activities, put it at the very tipsy-top.
2590                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2591                mLruProcesses.add(app);
2592            }
2593            nextIndex = mLruProcessServiceStart;
2594        } else if (hasService) {
2595            // Process has services, put it at the top of the service list.
2596            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2597            mLruProcesses.add(mLruProcessActivityStart, app);
2598            nextIndex = mLruProcessServiceStart;
2599            mLruProcessActivityStart++;
2600        } else  {
2601            // Process not otherwise of interest, it goes to the top of the non-service area.
2602            int index = mLruProcessServiceStart;
2603            if (client != null) {
2604                // If there is a client, don't allow the process to be moved up higher
2605                // in the list than that client.
2606                int clientIndex = mLruProcesses.lastIndexOf(client);
2607                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2608                        + " when updating " + app);
2609                if (clientIndex <= lrui) {
2610                    // Don't allow the client index restriction to push it down farther in the
2611                    // list than it already is.
2612                    clientIndex = lrui;
2613                }
2614                if (clientIndex >= 0 && index > clientIndex) {
2615                    index = clientIndex;
2616                }
2617            }
2618            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2619            mLruProcesses.add(index, app);
2620            nextIndex = index-1;
2621            mLruProcessActivityStart++;
2622            mLruProcessServiceStart++;
2623        }
2624
2625        // If the app is currently using a content provider or service,
2626        // bump those processes as well.
2627        for (int j=app.connections.size()-1; j>=0; j--) {
2628            ConnectionRecord cr = app.connections.valueAt(j);
2629            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2630                    && cr.binding.service.app != null
2631                    && cr.binding.service.app.lruSeq != mLruSeq
2632                    && !cr.binding.service.app.persistent) {
2633                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2634                        "service connection", cr, app);
2635            }
2636        }
2637        for (int j=app.conProviders.size()-1; j>=0; j--) {
2638            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2639            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2640                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2641                        "provider reference", cpr, app);
2642            }
2643        }
2644    }
2645
2646    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2647        if (uid == Process.SYSTEM_UID) {
2648            // The system gets to run in any process.  If there are multiple
2649            // processes with the same uid, just pick the first (this
2650            // should never happen).
2651            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2652            if (procs == null) return null;
2653            final int N = procs.size();
2654            for (int i = 0; i < N; i++) {
2655                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2656            }
2657        }
2658        ProcessRecord proc = mProcessNames.get(processName, uid);
2659        if (false && proc != null && !keepIfLarge
2660                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2661                && proc.lastCachedPss >= 4000) {
2662            // Turn this condition on to cause killing to happen regularly, for testing.
2663            if (proc.baseProcessTracker != null) {
2664                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2665            }
2666            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2667        } else if (proc != null && !keepIfLarge
2668                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2669                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2670            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2671            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2672                if (proc.baseProcessTracker != null) {
2673                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2674                }
2675                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2676            }
2677        }
2678        return proc;
2679    }
2680
2681    void ensurePackageDexOpt(String packageName) {
2682        IPackageManager pm = AppGlobals.getPackageManager();
2683        try {
2684            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2685                mDidDexOpt = true;
2686            }
2687        } catch (RemoteException e) {
2688        }
2689    }
2690
2691    boolean isNextTransitionForward() {
2692        int transit = mWindowManager.getPendingAppTransition();
2693        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2694                || transit == AppTransition.TRANSIT_TASK_OPEN
2695                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2696    }
2697
2698    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2699            String processName, String abiOverride, int uid, Runnable crashHandler) {
2700        synchronized(this) {
2701            ApplicationInfo info = new ApplicationInfo();
2702            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2703            // For isolated processes, the former contains the parent's uid and the latter the
2704            // actual uid of the isolated process.
2705            // In the special case introduced by this method (which is, starting an isolated
2706            // process directly from the SystemServer without an actual parent app process) the
2707            // closest thing to a parent's uid is SYSTEM_UID.
2708            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2709            // the |isolated| logic in the ProcessRecord constructor.
2710            info.uid = Process.SYSTEM_UID;
2711            info.processName = processName;
2712            info.className = entryPoint;
2713            info.packageName = "android";
2714            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2715                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2716                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2717                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2718                    crashHandler);
2719            return proc != null ? proc.pid : 0;
2720        }
2721    }
2722
2723    final ProcessRecord startProcessLocked(String processName,
2724            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2725            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2726            boolean isolated, boolean keepIfLarge) {
2727        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2728                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2729                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2730                null /* crashHandler */);
2731    }
2732
2733    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2734            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2735            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2736            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2737        long startTime = SystemClock.elapsedRealtime();
2738        ProcessRecord app;
2739        if (!isolated) {
2740            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2741            checkTime(startTime, "startProcess: after getProcessRecord");
2742        } else {
2743            // If this is an isolated process, it can't re-use an existing process.
2744            app = null;
2745        }
2746        // We don't have to do anything more if:
2747        // (1) There is an existing application record; and
2748        // (2) The caller doesn't think it is dead, OR there is no thread
2749        //     object attached to it so we know it couldn't have crashed; and
2750        // (3) There is a pid assigned to it, so it is either starting or
2751        //     already running.
2752        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2753                + " app=" + app + " knownToBeDead=" + knownToBeDead
2754                + " thread=" + (app != null ? app.thread : null)
2755                + " pid=" + (app != null ? app.pid : -1));
2756        if (app != null && app.pid > 0) {
2757            if (!knownToBeDead || app.thread == null) {
2758                // We already have the app running, or are waiting for it to
2759                // come up (we have a pid but not yet its thread), so keep it.
2760                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2761                // If this is a new package in the process, add the package to the list
2762                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2763                checkTime(startTime, "startProcess: done, added package to proc");
2764                return app;
2765            }
2766
2767            // An application record is attached to a previous process,
2768            // clean it up now.
2769            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2770            checkTime(startTime, "startProcess: bad proc running, killing");
2771            Process.killProcessGroup(app.info.uid, app.pid);
2772            handleAppDiedLocked(app, true, true);
2773            checkTime(startTime, "startProcess: done killing old proc");
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            checkTime(startTime, "startProcess: creating new process record");
2810            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2811            app.crashHandler = crashHandler;
2812            if (app == null) {
2813                Slog.w(TAG, "Failed making new process record for "
2814                        + processName + "/" + info.uid + " isolated=" + isolated);
2815                return null;
2816            }
2817            mProcessNames.put(processName, app.uid, app);
2818            if (isolated) {
2819                mIsolatedProcesses.put(app.uid, app);
2820            }
2821            checkTime(startTime, "startProcess: done creating new process record");
2822        } else {
2823            // If this is a new package in the process, add the package to the list
2824            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2825            checkTime(startTime, "startProcess: added package to existing proc");
2826        }
2827
2828        // If the system is not ready yet, then hold off on starting this
2829        // process until it is.
2830        if (!mProcessesReady
2831                && !isAllowedWhileBooting(info)
2832                && !allowWhileBooting) {
2833            if (!mProcessesOnHold.contains(app)) {
2834                mProcessesOnHold.add(app);
2835            }
2836            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2837            checkTime(startTime, "startProcess: returning with proc on hold");
2838            return app;
2839        }
2840
2841        checkTime(startTime, "startProcess: stepping in to startProcess");
2842        startProcessLocked(
2843                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2844        checkTime(startTime, "startProcess: done starting proc!");
2845        return (app.pid != 0) ? app : null;
2846    }
2847
2848    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2849        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2850    }
2851
2852    private final void startProcessLocked(ProcessRecord app,
2853            String hostingType, String hostingNameStr) {
2854        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2855                null /* entryPoint */, null /* entryPointArgs */);
2856    }
2857
2858    private final void startProcessLocked(ProcessRecord app, String hostingType,
2859            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2860        long startTime = SystemClock.elapsedRealtime();
2861        if (app.pid > 0 && app.pid != MY_PID) {
2862            checkTime(startTime, "startProcess: removing from pids map");
2863            synchronized (mPidsSelfLocked) {
2864                mPidsSelfLocked.remove(app.pid);
2865                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2866            }
2867            checkTime(startTime, "startProcess: done removing from pids map");
2868            app.setPid(0);
2869        }
2870
2871        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2872                "startProcessLocked removing on hold: " + app);
2873        mProcessesOnHold.remove(app);
2874
2875        checkTime(startTime, "startProcess: starting to update cpu stats");
2876        updateCpuStats();
2877        checkTime(startTime, "startProcess: done updating cpu stats");
2878
2879        try {
2880            int uid = app.uid;
2881
2882            int[] gids = null;
2883            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2884            if (!app.isolated) {
2885                int[] permGids = null;
2886                try {
2887                    checkTime(startTime, "startProcess: getting gids from package manager");
2888                    final PackageManager pm = mContext.getPackageManager();
2889                    permGids = pm.getPackageGids(app.info.packageName);
2890
2891                    if (Environment.isExternalStorageEmulated()) {
2892                        checkTime(startTime, "startProcess: checking external storage perm");
2893                        if (pm.checkPermission(
2894                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2895                                app.info.packageName) == PERMISSION_GRANTED) {
2896                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2897                        } else {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2899                        }
2900                    }
2901                } catch (PackageManager.NameNotFoundException e) {
2902                    Slog.w(TAG, "Unable to retrieve gids", e);
2903                }
2904
2905                /*
2906                 * Add shared application and profile GIDs so applications can share some
2907                 * resources like shared libraries and access user-wide resources
2908                 */
2909                if (permGids == null) {
2910                    gids = new int[2];
2911                } else {
2912                    gids = new int[permGids.length + 2];
2913                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2914                }
2915                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2916                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2917            }
2918            checkTime(startTime, "startProcess: building args");
2919            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2920                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2921                        && mTopComponent != null
2922                        && app.processName.equals(mTopComponent.getPackageName())) {
2923                    uid = 0;
2924                }
2925                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2926                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2927                    uid = 0;
2928                }
2929            }
2930            int debugFlags = 0;
2931            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2932                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2933                // Also turn on CheckJNI for debuggable apps. It's quite
2934                // awkward to turn on otherwise.
2935                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2936            }
2937            // Run the app in safe mode if its manifest requests so or the
2938            // system is booted in safe mode.
2939            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2940                mSafeMode == true) {
2941                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2942            }
2943            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2944                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2945            }
2946            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2947                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2948            }
2949            if ("1".equals(SystemProperties.get("debug.assert"))) {
2950                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2951            }
2952
2953            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2954            if (requiredAbi == null) {
2955                requiredAbi = Build.SUPPORTED_ABIS[0];
2956            }
2957
2958            String instructionSet = null;
2959            if (app.info.primaryCpuAbi != null) {
2960                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2961            }
2962
2963            // Start the process.  It will either succeed and return a result containing
2964            // the PID of the new process, or else throw a RuntimeException.
2965            boolean isActivityProcess = (entryPoint == null);
2966            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2967            checkTime(startTime, "startProcess: asking zygote to start proc");
2968            Process.ProcessStartResult startResult = Process.start(entryPoint,
2969                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2970                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2971                    app.info.dataDir, entryPointArgs);
2972            checkTime(startTime, "startProcess: returned from zygote!");
2973
2974            if (app.isolated) {
2975                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2976            }
2977            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2978            checkTime(startTime, "startProcess: done updating battery stats");
2979
2980            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2981                    UserHandle.getUserId(uid), startResult.pid, uid,
2982                    app.processName, hostingType,
2983                    hostingNameStr != null ? hostingNameStr : "");
2984
2985            if (app.persistent) {
2986                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2987            }
2988
2989            checkTime(startTime, "startProcess: building log message");
2990            StringBuilder buf = mStringBuilder;
2991            buf.setLength(0);
2992            buf.append("Start proc ");
2993            buf.append(app.processName);
2994            if (!isActivityProcess) {
2995                buf.append(" [");
2996                buf.append(entryPoint);
2997                buf.append("]");
2998            }
2999            buf.append(" for ");
3000            buf.append(hostingType);
3001            if (hostingNameStr != null) {
3002                buf.append(" ");
3003                buf.append(hostingNameStr);
3004            }
3005            buf.append(": pid=");
3006            buf.append(startResult.pid);
3007            buf.append(" uid=");
3008            buf.append(uid);
3009            buf.append(" gids={");
3010            if (gids != null) {
3011                for (int gi=0; gi<gids.length; gi++) {
3012                    if (gi != 0) buf.append(", ");
3013                    buf.append(gids[gi]);
3014
3015                }
3016            }
3017            buf.append("}");
3018            if (requiredAbi != null) {
3019                buf.append(" abi=");
3020                buf.append(requiredAbi);
3021            }
3022            Slog.i(TAG, buf.toString());
3023            app.setPid(startResult.pid);
3024            app.usingWrapper = startResult.usingWrapper;
3025            app.removed = false;
3026            app.killed = false;
3027            app.killedByAm = false;
3028            checkTime(startTime, "startProcess: starting to update pids map");
3029            synchronized (mPidsSelfLocked) {
3030                this.mPidsSelfLocked.put(startResult.pid, app);
3031                if (isActivityProcess) {
3032                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3033                    msg.obj = app;
3034                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3035                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3036                }
3037            }
3038            checkTime(startTime, "startProcess: done updating pids map");
3039        } catch (RuntimeException e) {
3040            // XXX do better error recovery.
3041            app.setPid(0);
3042            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3043            if (app.isolated) {
3044                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3045            }
3046            Slog.e(TAG, "Failure starting process " + app.processName, e);
3047        }
3048    }
3049
3050    void updateUsageStats(ActivityRecord component, boolean resumed) {
3051        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3052        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3053        if (resumed) {
3054            if (mUsageStatsService != null) {
3055                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3056                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3057            }
3058            synchronized (stats) {
3059                stats.noteActivityResumedLocked(component.app.uid);
3060            }
3061        } else {
3062            if (mUsageStatsService != null) {
3063                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3064                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3065            }
3066            synchronized (stats) {
3067                stats.noteActivityPausedLocked(component.app.uid);
3068            }
3069        }
3070    }
3071
3072    Intent getHomeIntent() {
3073        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3074        intent.setComponent(mTopComponent);
3075        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3076            intent.addCategory(Intent.CATEGORY_HOME);
3077        }
3078        return intent;
3079    }
3080
3081    boolean startHomeActivityLocked(int userId) {
3082        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3083                && mTopAction == null) {
3084            // We are running in factory test mode, but unable to find
3085            // the factory test app, so just sit around displaying the
3086            // error message and don't try to start anything.
3087            return false;
3088        }
3089        Intent intent = getHomeIntent();
3090        ActivityInfo aInfo =
3091            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3092        if (aInfo != null) {
3093            intent.setComponent(new ComponentName(
3094                    aInfo.applicationInfo.packageName, aInfo.name));
3095            // Don't do this if the home app is currently being
3096            // instrumented.
3097            aInfo = new ActivityInfo(aInfo);
3098            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3099            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3100                    aInfo.applicationInfo.uid, true);
3101            if (app == null || app.instrumentationClass == null) {
3102                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3103                mStackSupervisor.startHomeActivity(intent, aInfo);
3104            }
3105        }
3106
3107        return true;
3108    }
3109
3110    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3111        ActivityInfo ai = null;
3112        ComponentName comp = intent.getComponent();
3113        try {
3114            if (comp != null) {
3115                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3116            } else {
3117                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3118                        intent,
3119                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3120                            flags, userId);
3121
3122                if (info != null) {
3123                    ai = info.activityInfo;
3124                }
3125            }
3126        } catch (RemoteException e) {
3127            // ignore
3128        }
3129
3130        return ai;
3131    }
3132
3133    /**
3134     * Starts the "new version setup screen" if appropriate.
3135     */
3136    void startSetupActivityLocked() {
3137        // Only do this once per boot.
3138        if (mCheckedForSetup) {
3139            return;
3140        }
3141
3142        // We will show this screen if the current one is a different
3143        // version than the last one shown, and we are not running in
3144        // low-level factory test mode.
3145        final ContentResolver resolver = mContext.getContentResolver();
3146        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3147                Settings.Global.getInt(resolver,
3148                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3149            mCheckedForSetup = true;
3150
3151            // See if we should be showing the platform update setup UI.
3152            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3153            List<ResolveInfo> ris = mContext.getPackageManager()
3154                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3155
3156            // We don't allow third party apps to replace this.
3157            ResolveInfo ri = null;
3158            for (int i=0; ris != null && i<ris.size(); i++) {
3159                if ((ris.get(i).activityInfo.applicationInfo.flags
3160                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3161                    ri = ris.get(i);
3162                    break;
3163                }
3164            }
3165
3166            if (ri != null) {
3167                String vers = ri.activityInfo.metaData != null
3168                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3169                        : null;
3170                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3171                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3172                            Intent.METADATA_SETUP_VERSION);
3173                }
3174                String lastVers = Settings.Secure.getString(
3175                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3176                if (vers != null && !vers.equals(lastVers)) {
3177                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3178                    intent.setComponent(new ComponentName(
3179                            ri.activityInfo.packageName, ri.activityInfo.name));
3180                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3181                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3182                            null);
3183                }
3184            }
3185        }
3186    }
3187
3188    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3189        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3190    }
3191
3192    void enforceNotIsolatedCaller(String caller) {
3193        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3194            throw new SecurityException("Isolated process not allowed to call " + caller);
3195        }
3196    }
3197
3198    void enforceShellRestriction(String restriction, int userHandle) {
3199        if (Binder.getCallingUid() == Process.SHELL_UID) {
3200            if (userHandle < 0
3201                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3202                throw new SecurityException("Shell does not have permission to access user "
3203                        + userHandle);
3204            }
3205        }
3206    }
3207
3208    @Override
3209    public int getFrontActivityScreenCompatMode() {
3210        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3211        synchronized (this) {
3212            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3213        }
3214    }
3215
3216    @Override
3217    public void setFrontActivityScreenCompatMode(int mode) {
3218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3219                "setFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3222        }
3223    }
3224
3225    @Override
3226    public int getPackageScreenCompatMode(String packageName) {
3227        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3228        synchronized (this) {
3229            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3230        }
3231    }
3232
3233    @Override
3234    public void setPackageScreenCompatMode(String packageName, int mode) {
3235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3236                "setPackageScreenCompatMode");
3237        synchronized (this) {
3238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3239        }
3240    }
3241
3242    @Override
3243    public boolean getPackageAskScreenCompat(String packageName) {
3244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3245        synchronized (this) {
3246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3247        }
3248    }
3249
3250    @Override
3251    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setPackageAskScreenCompat");
3254        synchronized (this) {
3255            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3256        }
3257    }
3258
3259    private void dispatchProcessesChanged() {
3260        int N;
3261        synchronized (this) {
3262            N = mPendingProcessChanges.size();
3263            if (mActiveProcessChanges.length < N) {
3264                mActiveProcessChanges = new ProcessChangeItem[N];
3265            }
3266            mPendingProcessChanges.toArray(mActiveProcessChanges);
3267            mAvailProcessChanges.addAll(mPendingProcessChanges);
3268            mPendingProcessChanges.clear();
3269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3270        }
3271
3272        int i = mProcessObservers.beginBroadcast();
3273        while (i > 0) {
3274            i--;
3275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3276            if (observer != null) {
3277                try {
3278                    for (int j=0; j<N; j++) {
3279                        ProcessChangeItem item = mActiveProcessChanges[j];
3280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3282                                    + item.pid + " uid=" + item.uid + ": "
3283                                    + item.foregroundActivities);
3284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3285                                    item.foregroundActivities);
3286                        }
3287                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3289                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3290                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3291                        }
3292                    }
3293                } catch (RemoteException e) {
3294                }
3295            }
3296        }
3297        mProcessObservers.finishBroadcast();
3298    }
3299
3300    private void dispatchProcessDied(int pid, int uid) {
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    observer.onProcessDied(pid, uid);
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    @Override
3316    public final int startActivity(IApplicationThread caller, String callingPackage,
3317            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3318            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3319        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3320            resultWho, requestCode, startFlags, profilerInfo, options,
3321            UserHandle.getCallingUserId());
3322    }
3323
3324    @Override
3325    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3326            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3327            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3328        enforceNotIsolatedCaller("startActivity");
3329        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3330                false, ALLOW_FULL_ONLY, "startActivity", null);
3331        // TODO: Switch to user app stacks here.
3332        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3333                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3334                profilerInfo, null, null, options, userId, null, null);
3335    }
3336
3337    @Override
3338    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3339            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3340            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3341
3342        // This is very dangerous -- it allows you to perform a start activity (including
3343        // permission grants) as any app that may launch one of your own activities.  So
3344        // we will only allow this to be done from activities that are part of the core framework,
3345        // and then only when they are running as the system.
3346        final ActivityRecord sourceRecord;
3347        final int targetUid;
3348        final String targetPackage;
3349        synchronized (this) {
3350            if (resultTo == null) {
3351                throw new SecurityException("Must be called from an activity");
3352            }
3353            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3354            if (sourceRecord == null) {
3355                throw new SecurityException("Called with bad activity token: " + resultTo);
3356            }
3357            if (!sourceRecord.info.packageName.equals("android")) {
3358                throw new SecurityException(
3359                        "Must be called from an activity that is declared in the android package");
3360            }
3361            if (sourceRecord.app == null) {
3362                throw new SecurityException("Called without a process attached to activity");
3363            }
3364            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3365                // This is still okay, as long as this activity is running under the
3366                // uid of the original calling activity.
3367                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3368                    throw new SecurityException(
3369                            "Calling activity in uid " + sourceRecord.app.uid
3370                                    + " must be system uid or original calling uid "
3371                                    + sourceRecord.launchedFromUid);
3372                }
3373            }
3374            targetUid = sourceRecord.launchedFromUid;
3375            targetPackage = sourceRecord.launchedFromPackage;
3376        }
3377
3378        if (userId == UserHandle.USER_NULL) {
3379            userId = UserHandle.getUserId(sourceRecord.app.uid);
3380        }
3381
3382        // TODO: Switch to user app stacks here.
3383        try {
3384            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3385                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3386                    null, null, options, userId, null, null);
3387            return ret;
3388        } catch (SecurityException e) {
3389            // XXX need to figure out how to propagate to original app.
3390            // A SecurityException here is generally actually a fault of the original
3391            // calling activity (such as a fairly granting permissions), so propagate it
3392            // back to them.
3393            /*
3394            StringBuilder msg = new StringBuilder();
3395            msg.append("While launching");
3396            msg.append(intent.toString());
3397            msg.append(": ");
3398            msg.append(e.getMessage());
3399            */
3400            throw e;
3401        }
3402    }
3403
3404    @Override
3405    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3406            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3407            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3408        enforceNotIsolatedCaller("startActivityAndWait");
3409        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3410                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3411        WaitResult res = new WaitResult();
3412        // TODO: Switch to user app stacks here.
3413        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3414                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3415                options, userId, null, null);
3416        return res;
3417    }
3418
3419    @Override
3420    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3421            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3422            int startFlags, Configuration config, Bundle options, int userId) {
3423        enforceNotIsolatedCaller("startActivityWithConfig");
3424        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3425                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3426        // TODO: Switch to user app stacks here.
3427        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3428                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3429                null, null, config, options, userId, null, null);
3430        return ret;
3431    }
3432
3433    @Override
3434    public int startActivityIntentSender(IApplicationThread caller,
3435            IntentSender intent, Intent fillInIntent, String resolvedType,
3436            IBinder resultTo, String resultWho, int requestCode,
3437            int flagsMask, int flagsValues, Bundle options) {
3438        enforceNotIsolatedCaller("startActivityIntentSender");
3439        // Refuse possible leaked file descriptors
3440        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3441            throw new IllegalArgumentException("File descriptors passed in Intent");
3442        }
3443
3444        IIntentSender sender = intent.getTarget();
3445        if (!(sender instanceof PendingIntentRecord)) {
3446            throw new IllegalArgumentException("Bad PendingIntent object");
3447        }
3448
3449        PendingIntentRecord pir = (PendingIntentRecord)sender;
3450
3451        synchronized (this) {
3452            // If this is coming from the currently resumed activity, it is
3453            // effectively saying that app switches are allowed at this point.
3454            final ActivityStack stack = getFocusedStack();
3455            if (stack.mResumedActivity != null &&
3456                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3457                mAppSwitchesAllowedTime = 0;
3458            }
3459        }
3460        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3461                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3462        return ret;
3463    }
3464
3465    @Override
3466    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3467            Intent intent, String resolvedType, IVoiceInteractionSession session,
3468            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3469            Bundle options, int userId) {
3470        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3471                != PackageManager.PERMISSION_GRANTED) {
3472            String msg = "Permission Denial: startVoiceActivity() from pid="
3473                    + Binder.getCallingPid()
3474                    + ", uid=" + Binder.getCallingUid()
3475                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3476            Slog.w(TAG, msg);
3477            throw new SecurityException(msg);
3478        }
3479        if (session == null || interactor == null) {
3480            throw new NullPointerException("null session or interactor");
3481        }
3482        userId = handleIncomingUser(callingPid, callingUid, userId,
3483                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3484        // TODO: Switch to user app stacks here.
3485        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3486                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3487                null, options, userId, null, null);
3488    }
3489
3490    @Override
3491    public boolean startNextMatchingActivity(IBinder callingActivity,
3492            Intent intent, Bundle options) {
3493        // Refuse possible leaked file descriptors
3494        if (intent != null && intent.hasFileDescriptors() == true) {
3495            throw new IllegalArgumentException("File descriptors passed in Intent");
3496        }
3497
3498        synchronized (this) {
3499            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3500            if (r == null) {
3501                ActivityOptions.abort(options);
3502                return false;
3503            }
3504            if (r.app == null || r.app.thread == null) {
3505                // The caller is not running...  d'oh!
3506                ActivityOptions.abort(options);
3507                return false;
3508            }
3509            intent = new Intent(intent);
3510            // The caller is not allowed to change the data.
3511            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3512            // And we are resetting to find the next component...
3513            intent.setComponent(null);
3514
3515            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3516
3517            ActivityInfo aInfo = null;
3518            try {
3519                List<ResolveInfo> resolves =
3520                    AppGlobals.getPackageManager().queryIntentActivities(
3521                            intent, r.resolvedType,
3522                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3523                            UserHandle.getCallingUserId());
3524
3525                // Look for the original activity in the list...
3526                final int N = resolves != null ? resolves.size() : 0;
3527                for (int i=0; i<N; i++) {
3528                    ResolveInfo rInfo = resolves.get(i);
3529                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3530                            && rInfo.activityInfo.name.equals(r.info.name)) {
3531                        // We found the current one...  the next matching is
3532                        // after it.
3533                        i++;
3534                        if (i<N) {
3535                            aInfo = resolves.get(i).activityInfo;
3536                        }
3537                        if (debug) {
3538                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3539                                    + "/" + r.info.name);
3540                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3541                                    + "/" + aInfo.name);
3542                        }
3543                        break;
3544                    }
3545                }
3546            } catch (RemoteException e) {
3547            }
3548
3549            if (aInfo == null) {
3550                // Nobody who is next!
3551                ActivityOptions.abort(options);
3552                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3553                return false;
3554            }
3555
3556            intent.setComponent(new ComponentName(
3557                    aInfo.applicationInfo.packageName, aInfo.name));
3558            intent.setFlags(intent.getFlags()&~(
3559                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3560                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3561                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3562                    Intent.FLAG_ACTIVITY_NEW_TASK));
3563
3564            // Okay now we need to start the new activity, replacing the
3565            // currently running activity.  This is a little tricky because
3566            // we want to start the new one as if the current one is finished,
3567            // but not finish the current one first so that there is no flicker.
3568            // And thus...
3569            final boolean wasFinishing = r.finishing;
3570            r.finishing = true;
3571
3572            // Propagate reply information over to the new activity.
3573            final ActivityRecord resultTo = r.resultTo;
3574            final String resultWho = r.resultWho;
3575            final int requestCode = r.requestCode;
3576            r.resultTo = null;
3577            if (resultTo != null) {
3578                resultTo.removeResultsLocked(r, resultWho, requestCode);
3579            }
3580
3581            final long origId = Binder.clearCallingIdentity();
3582            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3583                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3584                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3585                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3586            Binder.restoreCallingIdentity(origId);
3587
3588            r.finishing = wasFinishing;
3589            if (res != ActivityManager.START_SUCCESS) {
3590                return false;
3591            }
3592            return true;
3593        }
3594    }
3595
3596    @Override
3597    public final int startActivityFromRecents(int taskId, Bundle options) {
3598        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3599            String msg = "Permission Denial: startActivityFromRecents called without " +
3600                    START_TASKS_FROM_RECENTS;
3601            Slog.w(TAG, msg);
3602            throw new SecurityException(msg);
3603        }
3604        return startActivityFromRecentsInner(taskId, options);
3605    }
3606
3607    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3608        final TaskRecord task;
3609        final int callingUid;
3610        final String callingPackage;
3611        final Intent intent;
3612        final int userId;
3613        synchronized (this) {
3614            task = recentTaskForIdLocked(taskId);
3615            if (task == null) {
3616                throw new IllegalArgumentException("Task " + taskId + " not found.");
3617            }
3618            callingUid = task.mCallingUid;
3619            callingPackage = task.mCallingPackage;
3620            intent = task.intent;
3621            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3622            userId = task.userId;
3623        }
3624        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3625                options, userId, null, task);
3626    }
3627
3628    final int startActivityInPackage(int uid, String callingPackage,
3629            Intent intent, String resolvedType, IBinder resultTo,
3630            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3631            IActivityContainer container, TaskRecord inTask) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635
3636        // TODO: Switch to user app stacks here.
3637        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3638                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3639                null, null, null, options, userId, container, inTask);
3640        return ret;
3641    }
3642
3643    @Override
3644    public final int startActivities(IApplicationThread caller, String callingPackage,
3645            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3646            int userId) {
3647        enforceNotIsolatedCaller("startActivities");
3648        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3649                false, ALLOW_FULL_ONLY, "startActivity", null);
3650        // TODO: Switch to user app stacks here.
3651        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3652                resolvedTypes, resultTo, options, userId);
3653        return ret;
3654    }
3655
3656    final int startActivitiesInPackage(int uid, String callingPackage,
3657            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3658            Bundle options, int userId) {
3659
3660        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3661                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3662        // TODO: Switch to user app stacks here.
3663        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3664                resultTo, options, userId);
3665        return ret;
3666    }
3667
3668    //explicitly remove thd old information in mRecentTasks when removing existing user.
3669    private void removeRecentTasksForUserLocked(int userId) {
3670        if(userId <= 0) {
3671            Slog.i(TAG, "Can't remove recent task on user " + userId);
3672            return;
3673        }
3674
3675        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3676            TaskRecord tr = mRecentTasks.get(i);
3677            if (tr.userId == userId) {
3678                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3679                        + " when finishing user" + userId);
3680                mRecentTasks.remove(i);
3681                tr.removedFromRecents();
3682            }
3683        }
3684
3685        // Remove tasks from persistent storage.
3686        notifyTaskPersisterLocked(null, true);
3687    }
3688
3689    // Sort by taskId
3690    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3691        @Override
3692        public int compare(TaskRecord lhs, TaskRecord rhs) {
3693            return rhs.taskId - lhs.taskId;
3694        }
3695    };
3696
3697    // Extract the affiliates of the chain containing mRecentTasks[start].
3698    private int processNextAffiliateChainLocked(int start) {
3699        final TaskRecord startTask = mRecentTasks.get(start);
3700        final int affiliateId = startTask.mAffiliatedTaskId;
3701
3702        // Quick identification of isolated tasks. I.e. those not launched behind.
3703        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3704                startTask.mNextAffiliate == null) {
3705            // There is still a slim chance that there are other tasks that point to this task
3706            // and that the chain is so messed up that this task no longer points to them but
3707            // the gain of this optimization outweighs the risk.
3708            startTask.inRecents = true;
3709            return start + 1;
3710        }
3711
3712        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3713        mTmpRecents.clear();
3714        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3715            final TaskRecord task = mRecentTasks.get(i);
3716            if (task.mAffiliatedTaskId == affiliateId) {
3717                mRecentTasks.remove(i);
3718                mTmpRecents.add(task);
3719            }
3720        }
3721
3722        // Sort them all by taskId. That is the order they were create in and that order will
3723        // always be correct.
3724        Collections.sort(mTmpRecents, mTaskRecordComparator);
3725
3726        // Go through and fix up the linked list.
3727        // The first one is the end of the chain and has no next.
3728        final TaskRecord first = mTmpRecents.get(0);
3729        first.inRecents = true;
3730        if (first.mNextAffiliate != null) {
3731            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3732            first.setNextAffiliate(null);
3733            notifyTaskPersisterLocked(first, false);
3734        }
3735        // Everything in the middle is doubly linked from next to prev.
3736        final int tmpSize = mTmpRecents.size();
3737        for (int i = 0; i < tmpSize - 1; ++i) {
3738            final TaskRecord next = mTmpRecents.get(i);
3739            final TaskRecord prev = mTmpRecents.get(i + 1);
3740            if (next.mPrevAffiliate != prev) {
3741                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3742                        " setting prev=" + prev);
3743                next.setPrevAffiliate(prev);
3744                notifyTaskPersisterLocked(next, false);
3745            }
3746            if (prev.mNextAffiliate != next) {
3747                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3748                        " setting next=" + next);
3749                prev.setNextAffiliate(next);
3750                notifyTaskPersisterLocked(prev, false);
3751            }
3752            prev.inRecents = true;
3753        }
3754        // The last one is the beginning of the list and has no prev.
3755        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3756        if (last.mPrevAffiliate != null) {
3757            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3758            last.setPrevAffiliate(null);
3759            notifyTaskPersisterLocked(last, false);
3760        }
3761
3762        // Insert the group back into mRecentTasks at start.
3763        mRecentTasks.addAll(start, mTmpRecents);
3764
3765        // Let the caller know where we left off.
3766        return start + tmpSize;
3767    }
3768
3769    /**
3770     * Update the recent tasks lists: make sure tasks should still be here (their
3771     * applications / activities still exist), update their availability, fixup ordering
3772     * of affiliations.
3773     */
3774    void cleanupRecentTasksLocked(int userId) {
3775        if (mRecentTasks == null) {
3776            // Happens when called from the packagemanager broadcast before boot.
3777            return;
3778        }
3779
3780        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3781        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3782        final IPackageManager pm = AppGlobals.getPackageManager();
3783        final ActivityInfo dummyAct = new ActivityInfo();
3784        final ApplicationInfo dummyApp = new ApplicationInfo();
3785
3786        int N = mRecentTasks.size();
3787
3788        int[] users = userId == UserHandle.USER_ALL
3789                ? getUsersLocked() : new int[] { userId };
3790        for (int user : users) {
3791            for (int i = 0; i < N; i++) {
3792                TaskRecord task = mRecentTasks.get(i);
3793                if (task.userId != user) {
3794                    // Only look at tasks for the user ID of interest.
3795                    continue;
3796                }
3797                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3798                    // This situation is broken, and we should just get rid of it now.
3799                    mRecentTasks.remove(i);
3800                    task.removedFromRecents();
3801                    i--;
3802                    N--;
3803                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3804                    continue;
3805                }
3806                // Check whether this activity is currently available.
3807                if (task.realActivity != null) {
3808                    ActivityInfo ai = availActCache.get(task.realActivity);
3809                    if (ai == null) {
3810                        try {
3811                            ai = pm.getActivityInfo(task.realActivity,
3812                                    PackageManager.GET_UNINSTALLED_PACKAGES
3813                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3814                        } catch (RemoteException e) {
3815                            // Will never happen.
3816                            continue;
3817                        }
3818                        if (ai == null) {
3819                            ai = dummyAct;
3820                        }
3821                        availActCache.put(task.realActivity, ai);
3822                    }
3823                    if (ai == dummyAct) {
3824                        // This could be either because the activity no longer exists, or the
3825                        // app is temporarily gone.  For the former we want to remove the recents
3826                        // entry; for the latter we want to mark it as unavailable.
3827                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3828                        if (app == null) {
3829                            try {
3830                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3831                                        PackageManager.GET_UNINSTALLED_PACKAGES
3832                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3833                            } catch (RemoteException e) {
3834                                // Will never happen.
3835                                continue;
3836                            }
3837                            if (app == null) {
3838                                app = dummyApp;
3839                            }
3840                            availAppCache.put(task.realActivity.getPackageName(), app);
3841                        }
3842                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3843                            // Doesn't exist any more!  Good-bye.
3844                            mRecentTasks.remove(i);
3845                            task.removedFromRecents();
3846                            i--;
3847                            N--;
3848                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3849                            continue;
3850                        } else {
3851                            // Otherwise just not available for now.
3852                            if (task.isAvailable) {
3853                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3854                                        + task);
3855                            }
3856                            task.isAvailable = false;
3857                        }
3858                    } else {
3859                        if (!ai.enabled || !ai.applicationInfo.enabled
3860                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3861                            if (task.isAvailable) {
3862                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3863                                        + task + " (enabled=" + ai.enabled + "/"
3864                                        + ai.applicationInfo.enabled +  " flags="
3865                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3866                            }
3867                            task.isAvailable = false;
3868                        } else {
3869                            if (!task.isAvailable) {
3870                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3871                                        + task);
3872                            }
3873                            task.isAvailable = true;
3874                        }
3875                    }
3876                }
3877            }
3878        }
3879
3880        // Verify the affiliate chain for each task.
3881        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3882        }
3883
3884        mTmpRecents.clear();
3885        // mRecentTasks is now in sorted, affiliated order.
3886    }
3887
3888    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3889        int N = mRecentTasks.size();
3890        TaskRecord top = task;
3891        int topIndex = taskIndex;
3892        while (top.mNextAffiliate != null && topIndex > 0) {
3893            top = top.mNextAffiliate;
3894            topIndex--;
3895        }
3896        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3897                + topIndex + " from intial " + taskIndex);
3898        // Find the end of the chain, doing a sanity check along the way.
3899        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3900        int endIndex = topIndex;
3901        TaskRecord prev = top;
3902        while (endIndex < N) {
3903            TaskRecord cur = mRecentTasks.get(endIndex);
3904            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3905                    + endIndex + " " + cur);
3906            if (cur == top) {
3907                // Verify start of the chain.
3908                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3909                    Slog.wtf(TAG, "Bad chain @" + endIndex
3910                            + ": first task has next affiliate: " + prev);
3911                    sane = false;
3912                    break;
3913                }
3914            } else {
3915                // Verify middle of the chain's next points back to the one before.
3916                if (cur.mNextAffiliate != prev
3917                        || cur.mNextAffiliateTaskId != prev.taskId) {
3918                    Slog.wtf(TAG, "Bad chain @" + endIndex
3919                            + ": middle task " + cur + " @" + endIndex
3920                            + " has bad next affiliate "
3921                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3922                            + ", expected " + prev);
3923                    sane = false;
3924                    break;
3925                }
3926            }
3927            if (cur.mPrevAffiliateTaskId == -1) {
3928                // Chain ends here.
3929                if (cur.mPrevAffiliate != null) {
3930                    Slog.wtf(TAG, "Bad chain @" + endIndex
3931                            + ": last task " + cur + " has previous affiliate "
3932                            + cur.mPrevAffiliate);
3933                    sane = false;
3934                }
3935                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3936                break;
3937            } else {
3938                // Verify middle of the chain's prev points to a valid item.
3939                if (cur.mPrevAffiliate == null) {
3940                    Slog.wtf(TAG, "Bad chain @" + endIndex
3941                            + ": task " + cur + " has previous affiliate "
3942                            + cur.mPrevAffiliate + " but should be id "
3943                            + cur.mPrevAffiliate);
3944                    sane = false;
3945                    break;
3946                }
3947            }
3948            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3949                Slog.wtf(TAG, "Bad chain @" + endIndex
3950                        + ": task " + cur + " has affiliated id "
3951                        + cur.mAffiliatedTaskId + " but should be "
3952                        + task.mAffiliatedTaskId);
3953                sane = false;
3954                break;
3955            }
3956            prev = cur;
3957            endIndex++;
3958            if (endIndex >= N) {
3959                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3960                        + ": last task " + prev);
3961                sane = false;
3962                break;
3963            }
3964        }
3965        if (sane) {
3966            if (endIndex < taskIndex) {
3967                Slog.wtf(TAG, "Bad chain @" + endIndex
3968                        + ": did not extend to task " + task + " @" + taskIndex);
3969                sane = false;
3970            }
3971        }
3972        if (sane) {
3973            // All looks good, we can just move all of the affiliated tasks
3974            // to the top.
3975            for (int i=topIndex; i<=endIndex; i++) {
3976                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3977                        + " from " + i + " to " + (i-topIndex));
3978                TaskRecord cur = mRecentTasks.remove(i);
3979                mRecentTasks.add(i-topIndex, cur);
3980            }
3981            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3982                    + " to " + endIndex);
3983            return true;
3984        }
3985
3986        // Whoops, couldn't do it.
3987        return false;
3988    }
3989
3990    final void addRecentTaskLocked(TaskRecord task) {
3991        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3992                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3993
3994        int N = mRecentTasks.size();
3995        // Quick case: check if the top-most recent task is the same.
3996        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3997            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3998            return;
3999        }
4000        // Another quick case: check if this is part of a set of affiliated
4001        // tasks that are at the top.
4002        if (isAffiliated && N > 0 && task.inRecents
4003                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4004            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4005                    + " at top when adding " + task);
4006            return;
4007        }
4008        // Another quick case: never add voice sessions.
4009        if (task.voiceSession != null) {
4010            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4011            return;
4012        }
4013
4014        boolean needAffiliationFix = false;
4015
4016        // Slightly less quick case: the task is already in recents, so all we need
4017        // to do is move it.
4018        if (task.inRecents) {
4019            int taskIndex = mRecentTasks.indexOf(task);
4020            if (taskIndex >= 0) {
4021                if (!isAffiliated) {
4022                    // Simple case: this is not an affiliated task, so we just move it to the front.
4023                    mRecentTasks.remove(taskIndex);
4024                    mRecentTasks.add(0, task);
4025                    notifyTaskPersisterLocked(task, false);
4026                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4027                            + " from " + taskIndex);
4028                    return;
4029                } else {
4030                    // More complicated: need to keep all affiliated tasks together.
4031                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4032                        // All went well.
4033                        return;
4034                    }
4035
4036                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4037                    // everything and then go through our general path of adding a new task.
4038                    needAffiliationFix = true;
4039                }
4040            } else {
4041                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4042                needAffiliationFix = true;
4043            }
4044        }
4045
4046        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4047        trimRecentsForTaskLocked(task, true);
4048
4049        N = mRecentTasks.size();
4050        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4051            final TaskRecord tr = mRecentTasks.remove(N - 1);
4052            tr.removedFromRecents();
4053            N--;
4054        }
4055        task.inRecents = true;
4056        if (!isAffiliated || needAffiliationFix) {
4057            // If this is a simple non-affiliated task, or we had some failure trying to
4058            // handle it as part of an affilated task, then just place it at the top.
4059            mRecentTasks.add(0, task);
4060        } else if (isAffiliated) {
4061            // If this is a new affiliated task, then move all of the affiliated tasks
4062            // to the front and insert this new one.
4063            TaskRecord other = task.mNextAffiliate;
4064            if (other == null) {
4065                other = task.mPrevAffiliate;
4066            }
4067            if (other != null) {
4068                int otherIndex = mRecentTasks.indexOf(other);
4069                if (otherIndex >= 0) {
4070                    // Insert new task at appropriate location.
4071                    int taskIndex;
4072                    if (other == task.mNextAffiliate) {
4073                        // We found the index of our next affiliation, which is who is
4074                        // before us in the list, so add after that point.
4075                        taskIndex = otherIndex+1;
4076                    } else {
4077                        // We found the index of our previous affiliation, which is who is
4078                        // after us in the list, so add at their position.
4079                        taskIndex = otherIndex;
4080                    }
4081                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4082                            + taskIndex + ": " + task);
4083                    mRecentTasks.add(taskIndex, task);
4084
4085                    // Now move everything to the front.
4086                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4087                        // All went well.
4088                        return;
4089                    }
4090
4091                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4092                    // everything and then go through our general path of adding a new task.
4093                    needAffiliationFix = true;
4094                } else {
4095                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4096                            + other);
4097                    needAffiliationFix = true;
4098                }
4099            } else {
4100                if (DEBUG_RECENTS) Slog.d(TAG,
4101                        "addRecent: adding affiliated task without next/prev:" + task);
4102                needAffiliationFix = true;
4103            }
4104        }
4105        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4106
4107        if (needAffiliationFix) {
4108            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4109            cleanupRecentTasksLocked(task.userId);
4110        }
4111    }
4112
4113    /**
4114     * If needed, remove oldest existing entries in recents that are for the same kind
4115     * of task as the given one.
4116     */
4117    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4118        int N = mRecentTasks.size();
4119        final Intent intent = task.intent;
4120        final boolean document = intent != null && intent.isDocument();
4121
4122        int maxRecents = task.maxRecents - 1;
4123        for (int i=0; i<N; i++) {
4124            final TaskRecord tr = mRecentTasks.get(i);
4125            if (task != tr) {
4126                if (task.userId != tr.userId) {
4127                    continue;
4128                }
4129                if (i > MAX_RECENT_BITMAPS) {
4130                    tr.freeLastThumbnail();
4131                }
4132                final Intent trIntent = tr.intent;
4133                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4134                    (intent == null || !intent.filterEquals(trIntent))) {
4135                    continue;
4136                }
4137                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4138                if (document && trIsDocument) {
4139                    // These are the same document activity (not necessarily the same doc).
4140                    if (maxRecents > 0) {
4141                        --maxRecents;
4142                        continue;
4143                    }
4144                    // Hit the maximum number of documents for this task. Fall through
4145                    // and remove this document from recents.
4146                } else if (document || trIsDocument) {
4147                    // Only one of these is a document. Not the droid we're looking for.
4148                    continue;
4149                }
4150            }
4151
4152            if (!doTrim) {
4153                // If the caller is not actually asking for a trim, just tell them we reached
4154                // a point where the trim would happen.
4155                return i;
4156            }
4157
4158            // Either task and tr are the same or, their affinities match or their intents match
4159            // and neither of them is a document, or they are documents using the same activity
4160            // and their maxRecents has been reached.
4161            tr.disposeThumbnail();
4162            mRecentTasks.remove(i);
4163            if (task != tr) {
4164                tr.removedFromRecents();
4165            }
4166            i--;
4167            N--;
4168            if (task.intent == null) {
4169                // If the new recent task we are adding is not fully
4170                // specified, then replace it with the existing recent task.
4171                task = tr;
4172            }
4173            notifyTaskPersisterLocked(tr, false);
4174        }
4175
4176        return -1;
4177    }
4178
4179    @Override
4180    public void reportActivityFullyDrawn(IBinder token) {
4181        synchronized (this) {
4182            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4183            if (r == null) {
4184                return;
4185            }
4186            r.reportFullyDrawnLocked();
4187        }
4188    }
4189
4190    @Override
4191    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192        synchronized (this) {
4193            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4194            if (r == null) {
4195                return;
4196            }
4197            final long origId = Binder.clearCallingIdentity();
4198            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4199            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4200                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4201            if (config != null) {
4202                r.frozenBeforeDestroy = true;
4203                if (!updateConfigurationLocked(config, r, false, false)) {
4204                    mStackSupervisor.resumeTopActivitiesLocked();
4205                }
4206            }
4207            Binder.restoreCallingIdentity(origId);
4208        }
4209    }
4210
4211    @Override
4212    public int getRequestedOrientation(IBinder token) {
4213        synchronized (this) {
4214            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4215            if (r == null) {
4216                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4217            }
4218            return mWindowManager.getAppOrientation(r.appToken);
4219        }
4220    }
4221
4222    /**
4223     * This is the internal entry point for handling Activity.finish().
4224     *
4225     * @param token The Binder token referencing the Activity we want to finish.
4226     * @param resultCode Result code, if any, from this Activity.
4227     * @param resultData Result data (Intent), if any, from this Activity.
4228     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4229     *            the root Activity in the task.
4230     *
4231     * @return Returns true if the activity successfully finished, or false if it is still running.
4232     */
4233    @Override
4234    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4235            boolean finishTask) {
4236        // Refuse possible leaked file descriptors
4237        if (resultData != null && resultData.hasFileDescriptors() == true) {
4238            throw new IllegalArgumentException("File descriptors passed in Intent");
4239        }
4240
4241        synchronized(this) {
4242            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4243            if (r == null) {
4244                return true;
4245            }
4246            // Keep track of the root activity of the task before we finish it
4247            TaskRecord tr = r.task;
4248            ActivityRecord rootR = tr.getRootActivity();
4249            if (rootR == null) {
4250                Slog.w(TAG, "Finishing task with all activities already finished");
4251            }
4252            // Do not allow task to finish in Lock Task mode.
4253            if (tr == mStackSupervisor.mLockTaskModeTask) {
4254                if (rootR == r) {
4255                    Slog.i(TAG, "Not finishing task in lock task mode");
4256                    mStackSupervisor.showLockTaskToast();
4257                    return false;
4258                }
4259            }
4260            if (mController != null) {
4261                // Find the first activity that is not finishing.
4262                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4263                if (next != null) {
4264                    // ask watcher if this is allowed
4265                    boolean resumeOK = true;
4266                    try {
4267                        resumeOK = mController.activityResuming(next.packageName);
4268                    } catch (RemoteException e) {
4269                        mController = null;
4270                        Watchdog.getInstance().setActivityController(null);
4271                    }
4272
4273                    if (!resumeOK) {
4274                        Slog.i(TAG, "Not finishing activity because controller resumed");
4275                        return false;
4276                    }
4277                }
4278            }
4279            final long origId = Binder.clearCallingIdentity();
4280            try {
4281                boolean res;
4282                if (finishTask && r == rootR) {
4283                    // If requested, remove the task that is associated to this activity only if it
4284                    // was the root activity in the task. The result code and data is ignored
4285                    // because we don't support returning them across task boundaries.
4286                    res = removeTaskByIdLocked(tr.taskId, false);
4287                    if (!res) {
4288                        Slog.i(TAG, "Removing task failed to finish activity");
4289                    }
4290                } else {
4291                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4292                            resultData, "app-request", true);
4293                    if (!res) {
4294                        Slog.i(TAG, "Failed to finish by app-request");
4295                    }
4296                }
4297                return res;
4298            } finally {
4299                Binder.restoreCallingIdentity(origId);
4300            }
4301        }
4302    }
4303
4304    @Override
4305    public final void finishHeavyWeightApp() {
4306        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4307                != PackageManager.PERMISSION_GRANTED) {
4308            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4309                    + Binder.getCallingPid()
4310                    + ", uid=" + Binder.getCallingUid()
4311                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4312            Slog.w(TAG, msg);
4313            throw new SecurityException(msg);
4314        }
4315
4316        synchronized(this) {
4317            if (mHeavyWeightProcess == null) {
4318                return;
4319            }
4320
4321            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4322                    mHeavyWeightProcess.activities);
4323            for (int i=0; i<activities.size(); i++) {
4324                ActivityRecord r = activities.get(i);
4325                if (!r.finishing) {
4326                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4327                            null, "finish-heavy", true);
4328                }
4329            }
4330
4331            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4332                    mHeavyWeightProcess.userId, 0));
4333            mHeavyWeightProcess = null;
4334        }
4335    }
4336
4337    @Override
4338    public void crashApplication(int uid, int initialPid, String packageName,
4339            String message) {
4340        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4341                != PackageManager.PERMISSION_GRANTED) {
4342            String msg = "Permission Denial: crashApplication() from pid="
4343                    + Binder.getCallingPid()
4344                    + ", uid=" + Binder.getCallingUid()
4345                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4346            Slog.w(TAG, msg);
4347            throw new SecurityException(msg);
4348        }
4349
4350        synchronized(this) {
4351            ProcessRecord proc = null;
4352
4353            // Figure out which process to kill.  We don't trust that initialPid
4354            // still has any relation to current pids, so must scan through the
4355            // list.
4356            synchronized (mPidsSelfLocked) {
4357                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4358                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4359                    if (p.uid != uid) {
4360                        continue;
4361                    }
4362                    if (p.pid == initialPid) {
4363                        proc = p;
4364                        break;
4365                    }
4366                    if (p.pkgList.containsKey(packageName)) {
4367                        proc = p;
4368                    }
4369                }
4370            }
4371
4372            if (proc == null) {
4373                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4374                        + " initialPid=" + initialPid
4375                        + " packageName=" + packageName);
4376                return;
4377            }
4378
4379            if (proc.thread != null) {
4380                if (proc.pid == Process.myPid()) {
4381                    Log.w(TAG, "crashApplication: trying to crash self!");
4382                    return;
4383                }
4384                long ident = Binder.clearCallingIdentity();
4385                try {
4386                    proc.thread.scheduleCrash(message);
4387                } catch (RemoteException e) {
4388                }
4389                Binder.restoreCallingIdentity(ident);
4390            }
4391        }
4392    }
4393
4394    @Override
4395    public final void finishSubActivity(IBinder token, String resultWho,
4396            int requestCode) {
4397        synchronized(this) {
4398            final long origId = Binder.clearCallingIdentity();
4399            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4400            if (r != null) {
4401                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4402            }
4403            Binder.restoreCallingIdentity(origId);
4404        }
4405    }
4406
4407    @Override
4408    public boolean finishActivityAffinity(IBinder token) {
4409        synchronized(this) {
4410            final long origId = Binder.clearCallingIdentity();
4411            try {
4412                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4413
4414                ActivityRecord rootR = r.task.getRootActivity();
4415                // Do not allow task to finish in Lock Task mode.
4416                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4417                    if (rootR == r) {
4418                        mStackSupervisor.showLockTaskToast();
4419                        return false;
4420                    }
4421                }
4422                boolean res = false;
4423                if (r != null) {
4424                    res = r.task.stack.finishActivityAffinityLocked(r);
4425                }
4426                return res;
4427            } finally {
4428                Binder.restoreCallingIdentity(origId);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public void finishVoiceTask(IVoiceInteractionSession session) {
4435        synchronized(this) {
4436            final long origId = Binder.clearCallingIdentity();
4437            try {
4438                mStackSupervisor.finishVoiceTask(session);
4439            } finally {
4440                Binder.restoreCallingIdentity(origId);
4441            }
4442        }
4443
4444    }
4445
4446    @Override
4447    public boolean releaseActivityInstance(IBinder token) {
4448        synchronized(this) {
4449            final long origId = Binder.clearCallingIdentity();
4450            try {
4451                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4452                if (r.task == null || r.task.stack == null) {
4453                    return false;
4454                }
4455                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4456            } finally {
4457                Binder.restoreCallingIdentity(origId);
4458            }
4459        }
4460    }
4461
4462    @Override
4463    public void releaseSomeActivities(IApplicationThread appInt) {
4464        synchronized(this) {
4465            final long origId = Binder.clearCallingIdentity();
4466            try {
4467                ProcessRecord app = getRecordForAppLocked(appInt);
4468                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4469            } finally {
4470                Binder.restoreCallingIdentity(origId);
4471            }
4472        }
4473    }
4474
4475    @Override
4476    public boolean willActivityBeVisible(IBinder token) {
4477        synchronized(this) {
4478            ActivityStack stack = ActivityRecord.getStackLocked(token);
4479            if (stack != null) {
4480                return stack.willActivityBeVisibleLocked(token);
4481            }
4482            return false;
4483        }
4484    }
4485
4486    @Override
4487    public void overridePendingTransition(IBinder token, String packageName,
4488            int enterAnim, int exitAnim) {
4489        synchronized(this) {
4490            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4491            if (self == null) {
4492                return;
4493            }
4494
4495            final long origId = Binder.clearCallingIdentity();
4496
4497            if (self.state == ActivityState.RESUMED
4498                    || self.state == ActivityState.PAUSING) {
4499                mWindowManager.overridePendingAppTransition(packageName,
4500                        enterAnim, exitAnim, null);
4501            }
4502
4503            Binder.restoreCallingIdentity(origId);
4504        }
4505    }
4506
4507    /**
4508     * Main function for removing an existing process from the activity manager
4509     * as a result of that process going away.  Clears out all connections
4510     * to the process.
4511     */
4512    private final void handleAppDiedLocked(ProcessRecord app,
4513            boolean restarting, boolean allowRestart) {
4514        int pid = app.pid;
4515        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4516        if (!kept && !restarting) {
4517            removeLruProcessLocked(app);
4518            if (pid > 0) {
4519                ProcessList.remove(pid);
4520            }
4521        }
4522
4523        if (mProfileProc == app) {
4524            clearProfilerLocked();
4525        }
4526
4527        // Remove this application's activities from active lists.
4528        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4529
4530        app.activities.clear();
4531
4532        if (app.instrumentationClass != null) {
4533            Slog.w(TAG, "Crash of app " + app.processName
4534                  + " running instrumentation " + app.instrumentationClass);
4535            Bundle info = new Bundle();
4536            info.putString("shortMsg", "Process crashed.");
4537            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4538        }
4539
4540        if (!restarting) {
4541            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4542                // If there was nothing to resume, and we are not already
4543                // restarting this process, but there is a visible activity that
4544                // is hosted by the process...  then make sure all visible
4545                // activities are running, taking care of restarting this
4546                // process.
4547                if (hasVisibleActivities) {
4548                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4549                }
4550            }
4551        }
4552    }
4553
4554    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4555        IBinder threadBinder = thread.asBinder();
4556        // Find the application record.
4557        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4558            ProcessRecord rec = mLruProcesses.get(i);
4559            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4560                return i;
4561            }
4562        }
4563        return -1;
4564    }
4565
4566    final ProcessRecord getRecordForAppLocked(
4567            IApplicationThread thread) {
4568        if (thread == null) {
4569            return null;
4570        }
4571
4572        int appIndex = getLRURecordIndexForAppLocked(thread);
4573        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4574    }
4575
4576    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4577        // If there are no longer any background processes running,
4578        // and the app that died was not running instrumentation,
4579        // then tell everyone we are now low on memory.
4580        boolean haveBg = false;
4581        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4582            ProcessRecord rec = mLruProcesses.get(i);
4583            if (rec.thread != null
4584                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4585                haveBg = true;
4586                break;
4587            }
4588        }
4589
4590        if (!haveBg) {
4591            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4592            if (doReport) {
4593                long now = SystemClock.uptimeMillis();
4594                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4595                    doReport = false;
4596                } else {
4597                    mLastMemUsageReportTime = now;
4598                }
4599            }
4600            final ArrayList<ProcessMemInfo> memInfos
4601                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4602            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4603            long now = SystemClock.uptimeMillis();
4604            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4605                ProcessRecord rec = mLruProcesses.get(i);
4606                if (rec == dyingProc || rec.thread == null) {
4607                    continue;
4608                }
4609                if (doReport) {
4610                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4611                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4612                }
4613                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4614                    // The low memory report is overriding any current
4615                    // state for a GC request.  Make sure to do
4616                    // heavy/important/visible/foreground processes first.
4617                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4618                        rec.lastRequestedGc = 0;
4619                    } else {
4620                        rec.lastRequestedGc = rec.lastLowMemory;
4621                    }
4622                    rec.reportLowMemory = true;
4623                    rec.lastLowMemory = now;
4624                    mProcessesToGc.remove(rec);
4625                    addProcessToGcListLocked(rec);
4626                }
4627            }
4628            if (doReport) {
4629                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4630                mHandler.sendMessage(msg);
4631            }
4632            scheduleAppGcsLocked();
4633        }
4634    }
4635
4636    final void appDiedLocked(ProcessRecord app) {
4637       appDiedLocked(app, app.pid, app.thread);
4638    }
4639
4640    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4641        // First check if this ProcessRecord is actually active for the pid.
4642        synchronized (mPidsSelfLocked) {
4643            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4644            if (curProc != app) {
4645                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4646                return;
4647            }
4648        }
4649
4650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4651        synchronized (stats) {
4652            stats.noteProcessDiedLocked(app.info.uid, pid);
4653        }
4654
4655        Process.killProcessQuiet(pid);
4656        Process.killProcessGroup(app.info.uid, pid);
4657        app.killed = true;
4658
4659        // Clean up already done if the process has been re-started.
4660        if (app.pid == pid && app.thread != null &&
4661                app.thread.asBinder() == thread.asBinder()) {
4662            boolean doLowMem = app.instrumentationClass == null;
4663            boolean doOomAdj = doLowMem;
4664            if (!app.killedByAm) {
4665                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4666                        + ") has died");
4667                mAllowLowerMemLevel = true;
4668            } else {
4669                // Note that we always want to do oom adj to update our state with the
4670                // new number of procs.
4671                mAllowLowerMemLevel = false;
4672                doLowMem = false;
4673            }
4674            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4675            if (DEBUG_CLEANUP) Slog.v(
4676                TAG, "Dying app: " + app + ", pid: " + pid
4677                + ", thread: " + thread.asBinder());
4678            handleAppDiedLocked(app, false, true);
4679
4680            if (doOomAdj) {
4681                updateOomAdjLocked();
4682            }
4683            if (doLowMem) {
4684                doLowMemReportIfNeededLocked(app);
4685            }
4686        } else if (app.pid != pid) {
4687            // A new process has already been started.
4688            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4689                    + ") has died and restarted (pid " + app.pid + ").");
4690            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4691        } else if (DEBUG_PROCESSES) {
4692            Slog.d(TAG, "Received spurious death notification for thread "
4693                    + thread.asBinder());
4694        }
4695    }
4696
4697    /**
4698     * If a stack trace dump file is configured, dump process stack traces.
4699     * @param clearTraces causes the dump file to be erased prior to the new
4700     *    traces being written, if true; when false, the new traces will be
4701     *    appended to any existing file content.
4702     * @param firstPids of dalvik VM processes to dump stack traces for first
4703     * @param lastPids of dalvik VM processes to dump stack traces for last
4704     * @param nativeProcs optional list of native process names to dump stack crawls
4705     * @return file containing stack traces, or null if no dump file is configured
4706     */
4707    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4708            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4709        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4710        if (tracesPath == null || tracesPath.length() == 0) {
4711            return null;
4712        }
4713
4714        File tracesFile = new File(tracesPath);
4715        try {
4716            File tracesDir = tracesFile.getParentFile();
4717            if (!tracesDir.exists()) {
4718                tracesDir.mkdirs();
4719                if (!SELinux.restorecon(tracesDir)) {
4720                    return null;
4721                }
4722            }
4723            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4724
4725            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4726            tracesFile.createNewFile();
4727            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4728        } catch (IOException e) {
4729            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4730            return null;
4731        }
4732
4733        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4734        return tracesFile;
4735    }
4736
4737    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4738            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4739        // Use a FileObserver to detect when traces finish writing.
4740        // The order of traces is considered important to maintain for legibility.
4741        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4742            @Override
4743            public synchronized void onEvent(int event, String path) { notify(); }
4744        };
4745
4746        try {
4747            observer.startWatching();
4748
4749            // First collect all of the stacks of the most important pids.
4750            if (firstPids != null) {
4751                try {
4752                    int num = firstPids.size();
4753                    for (int i = 0; i < num; i++) {
4754                        synchronized (observer) {
4755                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4756                            observer.wait(200);  // Wait for write-close, give up after 200msec
4757                        }
4758                    }
4759                } catch (InterruptedException e) {
4760                    Slog.wtf(TAG, e);
4761                }
4762            }
4763
4764            // Next collect the stacks of the native pids
4765            if (nativeProcs != null) {
4766                int[] pids = Process.getPidsForCommands(nativeProcs);
4767                if (pids != null) {
4768                    for (int pid : pids) {
4769                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4770                    }
4771                }
4772            }
4773
4774            // Lastly, measure CPU usage.
4775            if (processCpuTracker != null) {
4776                processCpuTracker.init();
4777                System.gc();
4778                processCpuTracker.update();
4779                try {
4780                    synchronized (processCpuTracker) {
4781                        processCpuTracker.wait(500); // measure over 1/2 second.
4782                    }
4783                } catch (InterruptedException e) {
4784                }
4785                processCpuTracker.update();
4786
4787                // We'll take the stack crawls of just the top apps using CPU.
4788                final int N = processCpuTracker.countWorkingStats();
4789                int numProcs = 0;
4790                for (int i=0; i<N && numProcs<5; i++) {
4791                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4792                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4793                        numProcs++;
4794                        try {
4795                            synchronized (observer) {
4796                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4797                                observer.wait(200);  // Wait for write-close, give up after 200msec
4798                            }
4799                        } catch (InterruptedException e) {
4800                            Slog.wtf(TAG, e);
4801                        }
4802
4803                    }
4804                }
4805            }
4806        } finally {
4807            observer.stopWatching();
4808        }
4809    }
4810
4811    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4812        if (true || IS_USER_BUILD) {
4813            return;
4814        }
4815        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4816        if (tracesPath == null || tracesPath.length() == 0) {
4817            return;
4818        }
4819
4820        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4821        StrictMode.allowThreadDiskWrites();
4822        try {
4823            final File tracesFile = new File(tracesPath);
4824            final File tracesDir = tracesFile.getParentFile();
4825            final File tracesTmp = new File(tracesDir, "__tmp__");
4826            try {
4827                if (!tracesDir.exists()) {
4828                    tracesDir.mkdirs();
4829                    if (!SELinux.restorecon(tracesDir.getPath())) {
4830                        return;
4831                    }
4832                }
4833                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4834
4835                if (tracesFile.exists()) {
4836                    tracesTmp.delete();
4837                    tracesFile.renameTo(tracesTmp);
4838                }
4839                StringBuilder sb = new StringBuilder();
4840                Time tobj = new Time();
4841                tobj.set(System.currentTimeMillis());
4842                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4843                sb.append(": ");
4844                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4845                sb.append(" since ");
4846                sb.append(msg);
4847                FileOutputStream fos = new FileOutputStream(tracesFile);
4848                fos.write(sb.toString().getBytes());
4849                if (app == null) {
4850                    fos.write("\n*** No application process!".getBytes());
4851                }
4852                fos.close();
4853                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4854            } catch (IOException e) {
4855                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4856                return;
4857            }
4858
4859            if (app != null) {
4860                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4861                firstPids.add(app.pid);
4862                dumpStackTraces(tracesPath, firstPids, null, null, null);
4863            }
4864
4865            File lastTracesFile = null;
4866            File curTracesFile = null;
4867            for (int i=9; i>=0; i--) {
4868                String name = String.format(Locale.US, "slow%02d.txt", i);
4869                curTracesFile = new File(tracesDir, name);
4870                if (curTracesFile.exists()) {
4871                    if (lastTracesFile != null) {
4872                        curTracesFile.renameTo(lastTracesFile);
4873                    } else {
4874                        curTracesFile.delete();
4875                    }
4876                }
4877                lastTracesFile = curTracesFile;
4878            }
4879            tracesFile.renameTo(curTracesFile);
4880            if (tracesTmp.exists()) {
4881                tracesTmp.renameTo(tracesFile);
4882            }
4883        } finally {
4884            StrictMode.setThreadPolicy(oldPolicy);
4885        }
4886    }
4887
4888    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4889            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4890        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4891        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4892
4893        if (mController != null) {
4894            try {
4895                // 0 == continue, -1 = kill process immediately
4896                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4897                if (res < 0 && app.pid != MY_PID) {
4898                    app.kill("anr", true);
4899                }
4900            } catch (RemoteException e) {
4901                mController = null;
4902                Watchdog.getInstance().setActivityController(null);
4903            }
4904        }
4905
4906        long anrTime = SystemClock.uptimeMillis();
4907        if (MONITOR_CPU_USAGE) {
4908            updateCpuStatsNow();
4909        }
4910
4911        synchronized (this) {
4912            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4913            if (mShuttingDown) {
4914                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4915                return;
4916            } else if (app.notResponding) {
4917                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4918                return;
4919            } else if (app.crashing) {
4920                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4921                return;
4922            }
4923
4924            // In case we come through here for the same app before completing
4925            // this one, mark as anring now so we will bail out.
4926            app.notResponding = true;
4927
4928            // Log the ANR to the event log.
4929            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4930                    app.processName, app.info.flags, annotation);
4931
4932            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4933            firstPids.add(app.pid);
4934
4935            int parentPid = app.pid;
4936            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4937            if (parentPid != app.pid) firstPids.add(parentPid);
4938
4939            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4940
4941            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4942                ProcessRecord r = mLruProcesses.get(i);
4943                if (r != null && r.thread != null) {
4944                    int pid = r.pid;
4945                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4946                        if (r.persistent) {
4947                            firstPids.add(pid);
4948                        } else {
4949                            lastPids.put(pid, Boolean.TRUE);
4950                        }
4951                    }
4952                }
4953            }
4954        }
4955
4956        // Log the ANR to the main log.
4957        StringBuilder info = new StringBuilder();
4958        info.setLength(0);
4959        info.append("ANR in ").append(app.processName);
4960        if (activity != null && activity.shortComponentName != null) {
4961            info.append(" (").append(activity.shortComponentName).append(")");
4962        }
4963        info.append("\n");
4964        info.append("PID: ").append(app.pid).append("\n");
4965        if (annotation != null) {
4966            info.append("Reason: ").append(annotation).append("\n");
4967        }
4968        if (parent != null && parent != activity) {
4969            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4970        }
4971
4972        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4973
4974        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4975                NATIVE_STACKS_OF_INTEREST);
4976
4977        String cpuInfo = null;
4978        if (MONITOR_CPU_USAGE) {
4979            updateCpuStatsNow();
4980            synchronized (mProcessCpuTracker) {
4981                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4982            }
4983            info.append(processCpuTracker.printCurrentLoad());
4984            info.append(cpuInfo);
4985        }
4986
4987        info.append(processCpuTracker.printCurrentState(anrTime));
4988
4989        Slog.e(TAG, info.toString());
4990        if (tracesFile == null) {
4991            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4992            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4993        }
4994
4995        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4996                cpuInfo, tracesFile, null);
4997
4998        if (mController != null) {
4999            try {
5000                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5001                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5002                if (res != 0) {
5003                    if (res < 0 && app.pid != MY_PID) {
5004                        app.kill("anr", true);
5005                    } else {
5006                        synchronized (this) {
5007                            mServices.scheduleServiceTimeoutLocked(app);
5008                        }
5009                    }
5010                    return;
5011                }
5012            } catch (RemoteException e) {
5013                mController = null;
5014                Watchdog.getInstance().setActivityController(null);
5015            }
5016        }
5017
5018        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5019        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5020                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5021
5022        synchronized (this) {
5023            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5024                app.kill("bg anr", true);
5025                return;
5026            }
5027
5028            // Set the app's notResponding state, and look up the errorReportReceiver
5029            makeAppNotRespondingLocked(app,
5030                    activity != null ? activity.shortComponentName : null,
5031                    annotation != null ? "ANR " + annotation : "ANR",
5032                    info.toString());
5033
5034            // Bring up the infamous App Not Responding dialog
5035            Message msg = Message.obtain();
5036            HashMap<String, Object> map = new HashMap<String, Object>();
5037            msg.what = SHOW_NOT_RESPONDING_MSG;
5038            msg.obj = map;
5039            msg.arg1 = aboveSystem ? 1 : 0;
5040            map.put("app", app);
5041            if (activity != null) {
5042                map.put("activity", activity);
5043            }
5044
5045            mHandler.sendMessage(msg);
5046        }
5047    }
5048
5049    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5050        if (!mLaunchWarningShown) {
5051            mLaunchWarningShown = true;
5052            mHandler.post(new Runnable() {
5053                @Override
5054                public void run() {
5055                    synchronized (ActivityManagerService.this) {
5056                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5057                        d.show();
5058                        mHandler.postDelayed(new Runnable() {
5059                            @Override
5060                            public void run() {
5061                                synchronized (ActivityManagerService.this) {
5062                                    d.dismiss();
5063                                    mLaunchWarningShown = false;
5064                                }
5065                            }
5066                        }, 4000);
5067                    }
5068                }
5069            });
5070        }
5071    }
5072
5073    @Override
5074    public boolean clearApplicationUserData(final String packageName,
5075            final IPackageDataObserver observer, int userId) {
5076        enforceNotIsolatedCaller("clearApplicationUserData");
5077        int uid = Binder.getCallingUid();
5078        int pid = Binder.getCallingPid();
5079        userId = handleIncomingUser(pid, uid,
5080                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5081        long callingId = Binder.clearCallingIdentity();
5082        try {
5083            IPackageManager pm = AppGlobals.getPackageManager();
5084            int pkgUid = -1;
5085            synchronized(this) {
5086                try {
5087                    pkgUid = pm.getPackageUid(packageName, userId);
5088                } catch (RemoteException e) {
5089                }
5090                if (pkgUid == -1) {
5091                    Slog.w(TAG, "Invalid packageName: " + packageName);
5092                    if (observer != null) {
5093                        try {
5094                            observer.onRemoveCompleted(packageName, false);
5095                        } catch (RemoteException e) {
5096                            Slog.i(TAG, "Observer no longer exists.");
5097                        }
5098                    }
5099                    return false;
5100                }
5101                if (uid == pkgUid || checkComponentPermission(
5102                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5103                        pid, uid, -1, true)
5104                        == PackageManager.PERMISSION_GRANTED) {
5105                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5106                } else {
5107                    throw new SecurityException("PID " + pid + " does not have permission "
5108                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5109                                    + " of package " + packageName);
5110                }
5111
5112                // Remove all tasks match the cleared application package and user
5113                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5114                    final TaskRecord tr = mRecentTasks.get(i);
5115                    final String taskPackageName =
5116                            tr.getBaseIntent().getComponent().getPackageName();
5117                    if (tr.userId != userId) continue;
5118                    if (!taskPackageName.equals(packageName)) continue;
5119                    removeTaskByIdLocked(tr.taskId, false);
5120                }
5121            }
5122
5123            try {
5124                // Clear application user data
5125                pm.clearApplicationUserData(packageName, observer, userId);
5126
5127                synchronized(this) {
5128                    // Remove all permissions granted from/to this package
5129                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5130                }
5131
5132                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5133                        Uri.fromParts("package", packageName, null));
5134                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5135                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5136                        null, null, 0, null, null, null, false, false, userId);
5137            } catch (RemoteException e) {
5138            }
5139        } finally {
5140            Binder.restoreCallingIdentity(callingId);
5141        }
5142        return true;
5143    }
5144
5145    @Override
5146    public void killBackgroundProcesses(final String packageName, int userId) {
5147        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5148                != PackageManager.PERMISSION_GRANTED &&
5149                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5150                        != PackageManager.PERMISSION_GRANTED) {
5151            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5152                    + Binder.getCallingPid()
5153                    + ", uid=" + Binder.getCallingUid()
5154                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5155            Slog.w(TAG, msg);
5156            throw new SecurityException(msg);
5157        }
5158
5159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5160                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5161        long callingId = Binder.clearCallingIdentity();
5162        try {
5163            IPackageManager pm = AppGlobals.getPackageManager();
5164            synchronized(this) {
5165                int appId = -1;
5166                try {
5167                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5168                } catch (RemoteException e) {
5169                }
5170                if (appId == -1) {
5171                    Slog.w(TAG, "Invalid packageName: " + packageName);
5172                    return;
5173                }
5174                killPackageProcessesLocked(packageName, appId, userId,
5175                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5176            }
5177        } finally {
5178            Binder.restoreCallingIdentity(callingId);
5179        }
5180    }
5181
5182    @Override
5183    public void killAllBackgroundProcesses() {
5184        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5185                != PackageManager.PERMISSION_GRANTED) {
5186            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5187                    + Binder.getCallingPid()
5188                    + ", uid=" + Binder.getCallingUid()
5189                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5190            Slog.w(TAG, msg);
5191            throw new SecurityException(msg);
5192        }
5193
5194        long callingId = Binder.clearCallingIdentity();
5195        try {
5196            synchronized(this) {
5197                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5198                final int NP = mProcessNames.getMap().size();
5199                for (int ip=0; ip<NP; ip++) {
5200                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5201                    final int NA = apps.size();
5202                    for (int ia=0; ia<NA; ia++) {
5203                        ProcessRecord app = apps.valueAt(ia);
5204                        if (app.persistent) {
5205                            // we don't kill persistent processes
5206                            continue;
5207                        }
5208                        if (app.removed) {
5209                            procs.add(app);
5210                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5211                            app.removed = true;
5212                            procs.add(app);
5213                        }
5214                    }
5215                }
5216
5217                int N = procs.size();
5218                for (int i=0; i<N; i++) {
5219                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5220                }
5221                mAllowLowerMemLevel = true;
5222                updateOomAdjLocked();
5223                doLowMemReportIfNeededLocked(null);
5224            }
5225        } finally {
5226            Binder.restoreCallingIdentity(callingId);
5227        }
5228    }
5229
5230    @Override
5231    public void forceStopPackage(final String packageName, int userId) {
5232        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5233                != PackageManager.PERMISSION_GRANTED) {
5234            String msg = "Permission Denial: forceStopPackage() from pid="
5235                    + Binder.getCallingPid()
5236                    + ", uid=" + Binder.getCallingUid()
5237                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5238            Slog.w(TAG, msg);
5239            throw new SecurityException(msg);
5240        }
5241        final int callingPid = Binder.getCallingPid();
5242        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5243                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5244        long callingId = Binder.clearCallingIdentity();
5245        try {
5246            IPackageManager pm = AppGlobals.getPackageManager();
5247            synchronized(this) {
5248                int[] users = userId == UserHandle.USER_ALL
5249                        ? getUsersLocked() : new int[] { userId };
5250                for (int user : users) {
5251                    int pkgUid = -1;
5252                    try {
5253                        pkgUid = pm.getPackageUid(packageName, user);
5254                    } catch (RemoteException e) {
5255                    }
5256                    if (pkgUid == -1) {
5257                        Slog.w(TAG, "Invalid packageName: " + packageName);
5258                        continue;
5259                    }
5260                    try {
5261                        pm.setPackageStoppedState(packageName, true, user);
5262                    } catch (RemoteException e) {
5263                    } catch (IllegalArgumentException e) {
5264                        Slog.w(TAG, "Failed trying to unstop package "
5265                                + packageName + ": " + e);
5266                    }
5267                    if (isUserRunningLocked(user, false)) {
5268                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5269                    }
5270                }
5271            }
5272        } finally {
5273            Binder.restoreCallingIdentity(callingId);
5274        }
5275    }
5276
5277    @Override
5278    public void addPackageDependency(String packageName) {
5279        synchronized (this) {
5280            int callingPid = Binder.getCallingPid();
5281            if (callingPid == Process.myPid()) {
5282                //  Yeah, um, no.
5283                Slog.w(TAG, "Can't addPackageDependency on system process");
5284                return;
5285            }
5286            ProcessRecord proc;
5287            synchronized (mPidsSelfLocked) {
5288                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5289            }
5290            if (proc != null) {
5291                if (proc.pkgDeps == null) {
5292                    proc.pkgDeps = new ArraySet<String>(1);
5293                }
5294                proc.pkgDeps.add(packageName);
5295            }
5296        }
5297    }
5298
5299    /*
5300     * The pkg name and app id have to be specified.
5301     */
5302    @Override
5303    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5304        if (pkg == null) {
5305            return;
5306        }
5307        // Make sure the uid is valid.
5308        if (appid < 0) {
5309            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5310            return;
5311        }
5312        int callerUid = Binder.getCallingUid();
5313        // Only the system server can kill an application
5314        if (callerUid == Process.SYSTEM_UID) {
5315            // Post an aysnc message to kill the application
5316            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5317            msg.arg1 = appid;
5318            msg.arg2 = 0;
5319            Bundle bundle = new Bundle();
5320            bundle.putString("pkg", pkg);
5321            bundle.putString("reason", reason);
5322            msg.obj = bundle;
5323            mHandler.sendMessage(msg);
5324        } else {
5325            throw new SecurityException(callerUid + " cannot kill pkg: " +
5326                    pkg);
5327        }
5328    }
5329
5330    @Override
5331    public void closeSystemDialogs(String reason) {
5332        enforceNotIsolatedCaller("closeSystemDialogs");
5333
5334        final int pid = Binder.getCallingPid();
5335        final int uid = Binder.getCallingUid();
5336        final long origId = Binder.clearCallingIdentity();
5337        try {
5338            synchronized (this) {
5339                // Only allow this from foreground processes, so that background
5340                // applications can't abuse it to prevent system UI from being shown.
5341                if (uid >= Process.FIRST_APPLICATION_UID) {
5342                    ProcessRecord proc;
5343                    synchronized (mPidsSelfLocked) {
5344                        proc = mPidsSelfLocked.get(pid);
5345                    }
5346                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5347                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5348                                + " from background process " + proc);
5349                        return;
5350                    }
5351                }
5352                closeSystemDialogsLocked(reason);
5353            }
5354        } finally {
5355            Binder.restoreCallingIdentity(origId);
5356        }
5357    }
5358
5359    void closeSystemDialogsLocked(String reason) {
5360        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5361        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5362                | Intent.FLAG_RECEIVER_FOREGROUND);
5363        if (reason != null) {
5364            intent.putExtra("reason", reason);
5365        }
5366        mWindowManager.closeSystemDialogs(reason);
5367
5368        mStackSupervisor.closeSystemDialogsLocked();
5369
5370        broadcastIntentLocked(null, null, intent, null,
5371                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5372                Process.SYSTEM_UID, UserHandle.USER_ALL);
5373    }
5374
5375    @Override
5376    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5377        enforceNotIsolatedCaller("getProcessMemoryInfo");
5378        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5379        for (int i=pids.length-1; i>=0; i--) {
5380            ProcessRecord proc;
5381            int oomAdj;
5382            synchronized (this) {
5383                synchronized (mPidsSelfLocked) {
5384                    proc = mPidsSelfLocked.get(pids[i]);
5385                    oomAdj = proc != null ? proc.setAdj : 0;
5386                }
5387            }
5388            infos[i] = new Debug.MemoryInfo();
5389            Debug.getMemoryInfo(pids[i], infos[i]);
5390            if (proc != null) {
5391                synchronized (this) {
5392                    if (proc.thread != null && proc.setAdj == oomAdj) {
5393                        // Record this for posterity if the process has been stable.
5394                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5395                                infos[i].getTotalUss(), false, proc.pkgList);
5396                    }
5397                }
5398            }
5399        }
5400        return infos;
5401    }
5402
5403    @Override
5404    public long[] getProcessPss(int[] pids) {
5405        enforceNotIsolatedCaller("getProcessPss");
5406        long[] pss = new long[pids.length];
5407        for (int i=pids.length-1; i>=0; i--) {
5408            ProcessRecord proc;
5409            int oomAdj;
5410            synchronized (this) {
5411                synchronized (mPidsSelfLocked) {
5412                    proc = mPidsSelfLocked.get(pids[i]);
5413                    oomAdj = proc != null ? proc.setAdj : 0;
5414                }
5415            }
5416            long[] tmpUss = new long[1];
5417            pss[i] = Debug.getPss(pids[i], tmpUss);
5418            if (proc != null) {
5419                synchronized (this) {
5420                    if (proc.thread != null && proc.setAdj == oomAdj) {
5421                        // Record this for posterity if the process has been stable.
5422                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5423                    }
5424                }
5425            }
5426        }
5427        return pss;
5428    }
5429
5430    @Override
5431    public void killApplicationProcess(String processName, int uid) {
5432        if (processName == null) {
5433            return;
5434        }
5435
5436        int callerUid = Binder.getCallingUid();
5437        // Only the system server can kill an application
5438        if (callerUid == Process.SYSTEM_UID) {
5439            synchronized (this) {
5440                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5441                if (app != null && app.thread != null) {
5442                    try {
5443                        app.thread.scheduleSuicide();
5444                    } catch (RemoteException e) {
5445                        // If the other end already died, then our work here is done.
5446                    }
5447                } else {
5448                    Slog.w(TAG, "Process/uid not found attempting kill of "
5449                            + processName + " / " + uid);
5450                }
5451            }
5452        } else {
5453            throw new SecurityException(callerUid + " cannot kill app process: " +
5454                    processName);
5455        }
5456    }
5457
5458    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5459        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5460                false, true, false, false, UserHandle.getUserId(uid), reason);
5461        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5462                Uri.fromParts("package", packageName, null));
5463        if (!mProcessesReady) {
5464            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5465                    | Intent.FLAG_RECEIVER_FOREGROUND);
5466        }
5467        intent.putExtra(Intent.EXTRA_UID, uid);
5468        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5469        broadcastIntentLocked(null, null, intent,
5470                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5471                false, false,
5472                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5473    }
5474
5475    private void forceStopUserLocked(int userId, String reason) {
5476        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5477        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5478        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5479                | Intent.FLAG_RECEIVER_FOREGROUND);
5480        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5481        broadcastIntentLocked(null, null, intent,
5482                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5483                false, false,
5484                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5485    }
5486
5487    private final boolean killPackageProcessesLocked(String packageName, int appId,
5488            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5489            boolean doit, boolean evenPersistent, String reason) {
5490        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5491
5492        // Remove all processes this package may have touched: all with the
5493        // same UID (except for the system or root user), and all whose name
5494        // matches the package name.
5495        final int NP = mProcessNames.getMap().size();
5496        for (int ip=0; ip<NP; ip++) {
5497            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5498            final int NA = apps.size();
5499            for (int ia=0; ia<NA; ia++) {
5500                ProcessRecord app = apps.valueAt(ia);
5501                if (app.persistent && !evenPersistent) {
5502                    // we don't kill persistent processes
5503                    continue;
5504                }
5505                if (app.removed) {
5506                    if (doit) {
5507                        procs.add(app);
5508                    }
5509                    continue;
5510                }
5511
5512                // Skip process if it doesn't meet our oom adj requirement.
5513                if (app.setAdj < minOomAdj) {
5514                    continue;
5515                }
5516
5517                // If no package is specified, we call all processes under the
5518                // give user id.
5519                if (packageName == null) {
5520                    if (app.userId != userId) {
5521                        continue;
5522                    }
5523                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5524                        continue;
5525                    }
5526                // Package has been specified, we want to hit all processes
5527                // that match it.  We need to qualify this by the processes
5528                // that are running under the specified app and user ID.
5529                } else {
5530                    final boolean isDep = app.pkgDeps != null
5531                            && app.pkgDeps.contains(packageName);
5532                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5533                        continue;
5534                    }
5535                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5536                        continue;
5537                    }
5538                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5539                        continue;
5540                    }
5541                }
5542
5543                // Process has passed all conditions, kill it!
5544                if (!doit) {
5545                    return true;
5546                }
5547                app.removed = true;
5548                procs.add(app);
5549            }
5550        }
5551
5552        int N = procs.size();
5553        for (int i=0; i<N; i++) {
5554            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5555        }
5556        updateOomAdjLocked();
5557        return N > 0;
5558    }
5559
5560    private final boolean forceStopPackageLocked(String name, int appId,
5561            boolean callerWillRestart, boolean purgeCache, boolean doit,
5562            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5563        int i;
5564        int N;
5565
5566        if (userId == UserHandle.USER_ALL && name == null) {
5567            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5568        }
5569
5570        if (appId < 0 && name != null) {
5571            try {
5572                appId = UserHandle.getAppId(
5573                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5574            } catch (RemoteException e) {
5575            }
5576        }
5577
5578        if (doit) {
5579            if (name != null) {
5580                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5581                        + " user=" + userId + ": " + reason);
5582            } else {
5583                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5584            }
5585
5586            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5587            for (int ip=pmap.size()-1; ip>=0; ip--) {
5588                SparseArray<Long> ba = pmap.valueAt(ip);
5589                for (i=ba.size()-1; i>=0; i--) {
5590                    boolean remove = false;
5591                    final int entUid = ba.keyAt(i);
5592                    if (name != null) {
5593                        if (userId == UserHandle.USER_ALL) {
5594                            if (UserHandle.getAppId(entUid) == appId) {
5595                                remove = true;
5596                            }
5597                        } else {
5598                            if (entUid == UserHandle.getUid(userId, appId)) {
5599                                remove = true;
5600                            }
5601                        }
5602                    } else if (UserHandle.getUserId(entUid) == userId) {
5603                        remove = true;
5604                    }
5605                    if (remove) {
5606                        ba.removeAt(i);
5607                    }
5608                }
5609                if (ba.size() == 0) {
5610                    pmap.removeAt(ip);
5611                }
5612            }
5613        }
5614
5615        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5616                -100, callerWillRestart, true, doit, evenPersistent,
5617                name == null ? ("stop user " + userId) : ("stop " + name));
5618
5619        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5620            if (!doit) {
5621                return true;
5622            }
5623            didSomething = true;
5624        }
5625
5626        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5627            if (!doit) {
5628                return true;
5629            }
5630            didSomething = true;
5631        }
5632
5633        if (name == null) {
5634            // Remove all sticky broadcasts from this user.
5635            mStickyBroadcasts.remove(userId);
5636        }
5637
5638        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5639        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5640                userId, providers)) {
5641            if (!doit) {
5642                return true;
5643            }
5644            didSomething = true;
5645        }
5646        N = providers.size();
5647        for (i=0; i<N; i++) {
5648            removeDyingProviderLocked(null, providers.get(i), true);
5649        }
5650
5651        // Remove transient permissions granted from/to this package/user
5652        removeUriPermissionsForPackageLocked(name, userId, false);
5653
5654        if (name == null || uninstalling) {
5655            // Remove pending intents.  For now we only do this when force
5656            // stopping users, because we have some problems when doing this
5657            // for packages -- app widgets are not currently cleaned up for
5658            // such packages, so they can be left with bad pending intents.
5659            if (mIntentSenderRecords.size() > 0) {
5660                Iterator<WeakReference<PendingIntentRecord>> it
5661                        = mIntentSenderRecords.values().iterator();
5662                while (it.hasNext()) {
5663                    WeakReference<PendingIntentRecord> wpir = it.next();
5664                    if (wpir == null) {
5665                        it.remove();
5666                        continue;
5667                    }
5668                    PendingIntentRecord pir = wpir.get();
5669                    if (pir == null) {
5670                        it.remove();
5671                        continue;
5672                    }
5673                    if (name == null) {
5674                        // Stopping user, remove all objects for the user.
5675                        if (pir.key.userId != userId) {
5676                            // Not the same user, skip it.
5677                            continue;
5678                        }
5679                    } else {
5680                        if (UserHandle.getAppId(pir.uid) != appId) {
5681                            // Different app id, skip it.
5682                            continue;
5683                        }
5684                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5685                            // Different user, skip it.
5686                            continue;
5687                        }
5688                        if (!pir.key.packageName.equals(name)) {
5689                            // Different package, skip it.
5690                            continue;
5691                        }
5692                    }
5693                    if (!doit) {
5694                        return true;
5695                    }
5696                    didSomething = true;
5697                    it.remove();
5698                    pir.canceled = true;
5699                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5700                        pir.key.activity.pendingResults.remove(pir.ref);
5701                    }
5702                }
5703            }
5704        }
5705
5706        if (doit) {
5707            if (purgeCache && name != null) {
5708                AttributeCache ac = AttributeCache.instance();
5709                if (ac != null) {
5710                    ac.removePackage(name);
5711                }
5712            }
5713            if (mBooted) {
5714                mStackSupervisor.resumeTopActivitiesLocked();
5715                mStackSupervisor.scheduleIdleLocked();
5716            }
5717        }
5718
5719        return didSomething;
5720    }
5721
5722    private final boolean removeProcessLocked(ProcessRecord app,
5723            boolean callerWillRestart, boolean allowRestart, String reason) {
5724        final String name = app.processName;
5725        final int uid = app.uid;
5726        if (DEBUG_PROCESSES) Slog.d(
5727            TAG, "Force removing proc " + app.toShortString() + " (" + name
5728            + "/" + uid + ")");
5729
5730        mProcessNames.remove(name, uid);
5731        mIsolatedProcesses.remove(app.uid);
5732        if (mHeavyWeightProcess == app) {
5733            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5734                    mHeavyWeightProcess.userId, 0));
5735            mHeavyWeightProcess = null;
5736        }
5737        boolean needRestart = false;
5738        if (app.pid > 0 && app.pid != MY_PID) {
5739            int pid = app.pid;
5740            synchronized (mPidsSelfLocked) {
5741                mPidsSelfLocked.remove(pid);
5742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5743            }
5744            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5745            if (app.isolated) {
5746                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5747            }
5748            app.kill(reason, true);
5749            handleAppDiedLocked(app, true, allowRestart);
5750            removeLruProcessLocked(app);
5751
5752            if (app.persistent && !app.isolated) {
5753                if (!callerWillRestart) {
5754                    addAppLocked(app.info, false, null /* ABI override */);
5755                } else {
5756                    needRestart = true;
5757                }
5758            }
5759        } else {
5760            mRemovedProcesses.add(app);
5761        }
5762
5763        return needRestart;
5764    }
5765
5766    private final void processStartTimedOutLocked(ProcessRecord app) {
5767        final int pid = app.pid;
5768        boolean gone = false;
5769        synchronized (mPidsSelfLocked) {
5770            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5771            if (knownApp != null && knownApp.thread == null) {
5772                mPidsSelfLocked.remove(pid);
5773                gone = true;
5774            }
5775        }
5776
5777        if (gone) {
5778            Slog.w(TAG, "Process " + app + " failed to attach");
5779            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5780                    pid, app.uid, app.processName);
5781            mProcessNames.remove(app.processName, app.uid);
5782            mIsolatedProcesses.remove(app.uid);
5783            if (mHeavyWeightProcess == app) {
5784                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5785                        mHeavyWeightProcess.userId, 0));
5786                mHeavyWeightProcess = null;
5787            }
5788            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5789            if (app.isolated) {
5790                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5791            }
5792            // Take care of any launching providers waiting for this process.
5793            checkAppInLaunchingProvidersLocked(app, true);
5794            // Take care of any services that are waiting for the process.
5795            mServices.processStartTimedOutLocked(app);
5796            app.kill("start timeout", true);
5797            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5798                Slog.w(TAG, "Unattached app died before backup, skipping");
5799                try {
5800                    IBackupManager bm = IBackupManager.Stub.asInterface(
5801                            ServiceManager.getService(Context.BACKUP_SERVICE));
5802                    bm.agentDisconnected(app.info.packageName);
5803                } catch (RemoteException e) {
5804                    // Can't happen; the backup manager is local
5805                }
5806            }
5807            if (isPendingBroadcastProcessLocked(pid)) {
5808                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5809                skipPendingBroadcastLocked(pid);
5810            }
5811        } else {
5812            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5813        }
5814    }
5815
5816    private final boolean attachApplicationLocked(IApplicationThread thread,
5817            int pid) {
5818
5819        // Find the application record that is being attached...  either via
5820        // the pid if we are running in multiple processes, or just pull the
5821        // next app record if we are emulating process with anonymous threads.
5822        ProcessRecord app;
5823        if (pid != MY_PID && pid >= 0) {
5824            synchronized (mPidsSelfLocked) {
5825                app = mPidsSelfLocked.get(pid);
5826            }
5827        } else {
5828            app = null;
5829        }
5830
5831        if (app == null) {
5832            Slog.w(TAG, "No pending application record for pid " + pid
5833                    + " (IApplicationThread " + thread + "); dropping process");
5834            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5835            if (pid > 0 && pid != MY_PID) {
5836                Process.killProcessQuiet(pid);
5837                //TODO: Process.killProcessGroup(app.info.uid, pid);
5838            } else {
5839                try {
5840                    thread.scheduleExit();
5841                } catch (Exception e) {
5842                    // Ignore exceptions.
5843                }
5844            }
5845            return false;
5846        }
5847
5848        // If this application record is still attached to a previous
5849        // process, clean it up now.
5850        if (app.thread != null) {
5851            handleAppDiedLocked(app, true, true);
5852        }
5853
5854        // Tell the process all about itself.
5855
5856        if (localLOGV) Slog.v(
5857                TAG, "Binding process pid " + pid + " to record " + app);
5858
5859        final String processName = app.processName;
5860        try {
5861            AppDeathRecipient adr = new AppDeathRecipient(
5862                    app, pid, thread);
5863            thread.asBinder().linkToDeath(adr, 0);
5864            app.deathRecipient = adr;
5865        } catch (RemoteException e) {
5866            app.resetPackageList(mProcessStats);
5867            startProcessLocked(app, "link fail", processName);
5868            return false;
5869        }
5870
5871        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5872
5873        app.makeActive(thread, mProcessStats);
5874        app.curAdj = app.setAdj = -100;
5875        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5876        app.forcingToForeground = null;
5877        updateProcessForegroundLocked(app, false, false);
5878        app.hasShownUi = false;
5879        app.debugging = false;
5880        app.cached = false;
5881        app.killedByAm = false;
5882
5883        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5884
5885        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5886        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5887
5888        if (!normalMode) {
5889            Slog.i(TAG, "Launching preboot mode app: " + app);
5890        }
5891
5892        if (localLOGV) Slog.v(
5893            TAG, "New app record " + app
5894            + " thread=" + thread.asBinder() + " pid=" + pid);
5895        try {
5896            int testMode = IApplicationThread.DEBUG_OFF;
5897            if (mDebugApp != null && mDebugApp.equals(processName)) {
5898                testMode = mWaitForDebugger
5899                    ? IApplicationThread.DEBUG_WAIT
5900                    : IApplicationThread.DEBUG_ON;
5901                app.debugging = true;
5902                if (mDebugTransient) {
5903                    mDebugApp = mOrigDebugApp;
5904                    mWaitForDebugger = mOrigWaitForDebugger;
5905                }
5906            }
5907            String profileFile = app.instrumentationProfileFile;
5908            ParcelFileDescriptor profileFd = null;
5909            int samplingInterval = 0;
5910            boolean profileAutoStop = false;
5911            if (mProfileApp != null && mProfileApp.equals(processName)) {
5912                mProfileProc = app;
5913                profileFile = mProfileFile;
5914                profileFd = mProfileFd;
5915                samplingInterval = mSamplingInterval;
5916                profileAutoStop = mAutoStopProfiler;
5917            }
5918            boolean enableOpenGlTrace = false;
5919            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5920                enableOpenGlTrace = true;
5921                mOpenGlTraceApp = null;
5922            }
5923
5924            // If the app is being launched for restore or full backup, set it up specially
5925            boolean isRestrictedBackupMode = false;
5926            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5927                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5928                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5929                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5930            }
5931
5932            ensurePackageDexOpt(app.instrumentationInfo != null
5933                    ? app.instrumentationInfo.packageName
5934                    : app.info.packageName);
5935            if (app.instrumentationClass != null) {
5936                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5937            }
5938            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5939                    + processName + " with config " + mConfiguration);
5940            ApplicationInfo appInfo = app.instrumentationInfo != null
5941                    ? app.instrumentationInfo : app.info;
5942            app.compat = compatibilityInfoForPackageLocked(appInfo);
5943            if (profileFd != null) {
5944                profileFd = profileFd.dup();
5945            }
5946            ProfilerInfo profilerInfo = profileFile == null ? null
5947                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5948            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5949                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5950                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5951                    isRestrictedBackupMode || !normalMode, app.persistent,
5952                    new Configuration(mConfiguration), app.compat,
5953                    getCommonServicesLocked(app.isolated),
5954                    mCoreSettingsObserver.getCoreSettingsLocked());
5955            updateLruProcessLocked(app, false, null);
5956            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5957        } catch (Exception e) {
5958            // todo: Yikes!  What should we do?  For now we will try to
5959            // start another process, but that could easily get us in
5960            // an infinite loop of restarting processes...
5961            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5962
5963            app.resetPackageList(mProcessStats);
5964            app.unlinkDeathRecipient();
5965            startProcessLocked(app, "bind fail", processName);
5966            return false;
5967        }
5968
5969        // Remove this record from the list of starting applications.
5970        mPersistentStartingProcesses.remove(app);
5971        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5972                "Attach application locked removing on hold: " + app);
5973        mProcessesOnHold.remove(app);
5974
5975        boolean badApp = false;
5976        boolean didSomething = false;
5977
5978        // See if the top visible activity is waiting to run in this process...
5979        if (normalMode) {
5980            try {
5981                if (mStackSupervisor.attachApplicationLocked(app)) {
5982                    didSomething = true;
5983                }
5984            } catch (Exception e) {
5985                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5986                badApp = true;
5987            }
5988        }
5989
5990        // Find any services that should be running in this process...
5991        if (!badApp) {
5992            try {
5993                didSomething |= mServices.attachApplicationLocked(app, processName);
5994            } catch (Exception e) {
5995                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5996                badApp = true;
5997            }
5998        }
5999
6000        // Check if a next-broadcast receiver is in this process...
6001        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6002            try {
6003                didSomething |= sendPendingBroadcastsLocked(app);
6004            } catch (Exception e) {
6005                // If the app died trying to launch the receiver we declare it 'bad'
6006                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6007                badApp = true;
6008            }
6009        }
6010
6011        // Check whether the next backup agent is in this process...
6012        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6013            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6014            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6015            try {
6016                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6017                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6018                        mBackupTarget.backupMode);
6019            } catch (Exception e) {
6020                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6021                badApp = true;
6022            }
6023        }
6024
6025        if (badApp) {
6026            app.kill("error during init", true);
6027            handleAppDiedLocked(app, false, true);
6028            return false;
6029        }
6030
6031        if (!didSomething) {
6032            updateOomAdjLocked();
6033        }
6034
6035        return true;
6036    }
6037
6038    @Override
6039    public final void attachApplication(IApplicationThread thread) {
6040        synchronized (this) {
6041            int callingPid = Binder.getCallingPid();
6042            final long origId = Binder.clearCallingIdentity();
6043            attachApplicationLocked(thread, callingPid);
6044            Binder.restoreCallingIdentity(origId);
6045        }
6046    }
6047
6048    @Override
6049    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6050        final long origId = Binder.clearCallingIdentity();
6051        synchronized (this) {
6052            ActivityStack stack = ActivityRecord.getStackLocked(token);
6053            if (stack != null) {
6054                ActivityRecord r =
6055                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6056                if (stopProfiling) {
6057                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6058                        try {
6059                            mProfileFd.close();
6060                        } catch (IOException e) {
6061                        }
6062                        clearProfilerLocked();
6063                    }
6064                }
6065            }
6066        }
6067        Binder.restoreCallingIdentity(origId);
6068    }
6069
6070    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6071        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6072                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6073    }
6074
6075    void enableScreenAfterBoot() {
6076        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6077                SystemClock.uptimeMillis());
6078        mWindowManager.enableScreenAfterBoot();
6079
6080        synchronized (this) {
6081            updateEventDispatchingLocked();
6082        }
6083    }
6084
6085    @Override
6086    public void showBootMessage(final CharSequence msg, final boolean always) {
6087        enforceNotIsolatedCaller("showBootMessage");
6088        mWindowManager.showBootMessage(msg, always);
6089    }
6090
6091    @Override
6092    public void keyguardWaitingForActivityDrawn() {
6093        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6094        final long token = Binder.clearCallingIdentity();
6095        try {
6096            synchronized (this) {
6097                if (DEBUG_LOCKSCREEN) logLockScreen("");
6098                mWindowManager.keyguardWaitingForActivityDrawn();
6099                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6100                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6101                    updateSleepIfNeededLocked();
6102                }
6103            }
6104        } finally {
6105            Binder.restoreCallingIdentity(token);
6106        }
6107    }
6108
6109    final void finishBooting() {
6110        synchronized (this) {
6111            if (!mBootAnimationComplete) {
6112                mCallFinishBooting = true;
6113                return;
6114            }
6115            mCallFinishBooting = false;
6116        }
6117
6118        ArraySet<String> completedIsas = new ArraySet<String>();
6119        for (String abi : Build.SUPPORTED_ABIS) {
6120            Process.establishZygoteConnectionForAbi(abi);
6121            final String instructionSet = VMRuntime.getInstructionSet(abi);
6122            if (!completedIsas.contains(instructionSet)) {
6123                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6124                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6125                }
6126                completedIsas.add(instructionSet);
6127            }
6128        }
6129
6130        IntentFilter pkgFilter = new IntentFilter();
6131        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6132        pkgFilter.addDataScheme("package");
6133        mContext.registerReceiver(new BroadcastReceiver() {
6134            @Override
6135            public void onReceive(Context context, Intent intent) {
6136                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6137                if (pkgs != null) {
6138                    for (String pkg : pkgs) {
6139                        synchronized (ActivityManagerService.this) {
6140                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6141                                    0, "finished booting")) {
6142                                setResultCode(Activity.RESULT_OK);
6143                                return;
6144                            }
6145                        }
6146                    }
6147                }
6148            }
6149        }, pkgFilter);
6150
6151        // Let system services know.
6152        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6153
6154        synchronized (this) {
6155            // Ensure that any processes we had put on hold are now started
6156            // up.
6157            final int NP = mProcessesOnHold.size();
6158            if (NP > 0) {
6159                ArrayList<ProcessRecord> procs =
6160                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6161                for (int ip=0; ip<NP; ip++) {
6162                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6163                            + procs.get(ip));
6164                    startProcessLocked(procs.get(ip), "on-hold", null);
6165                }
6166            }
6167
6168            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6169                // Start looking for apps that are abusing wake locks.
6170                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6171                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6172                // Tell anyone interested that we are done booting!
6173                SystemProperties.set("sys.boot_completed", "1");
6174
6175                // And trigger dev.bootcomplete if we are not showing encryption progress
6176                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6177                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6178                    SystemProperties.set("dev.bootcomplete", "1");
6179                }
6180                for (int i=0; i<mStartedUsers.size(); i++) {
6181                    UserStartedState uss = mStartedUsers.valueAt(i);
6182                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6183                        uss.mState = UserStartedState.STATE_RUNNING;
6184                        final int userId = mStartedUsers.keyAt(i);
6185                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6186                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6187                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6188                        broadcastIntentLocked(null, null, intent, null,
6189                                new IIntentReceiver.Stub() {
6190                                    @Override
6191                                    public void performReceive(Intent intent, int resultCode,
6192                                            String data, Bundle extras, boolean ordered,
6193                                            boolean sticky, int sendingUser) {
6194                                        synchronized (ActivityManagerService.this) {
6195                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6196                                                    true, false);
6197                                        }
6198                                    }
6199                                },
6200                                0, null, null,
6201                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6202                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6203                                userId);
6204                    }
6205                }
6206                scheduleStartProfilesLocked();
6207            }
6208        }
6209    }
6210
6211    @Override
6212    public void bootAnimationComplete() {
6213        final boolean callFinishBooting;
6214        synchronized (this) {
6215            callFinishBooting = mCallFinishBooting;
6216            mBootAnimationComplete = true;
6217        }
6218        if (callFinishBooting) {
6219            finishBooting();
6220        }
6221    }
6222
6223    final void ensureBootCompleted() {
6224        boolean booting;
6225        boolean enableScreen;
6226        synchronized (this) {
6227            booting = mBooting;
6228            mBooting = false;
6229            enableScreen = !mBooted;
6230            mBooted = true;
6231        }
6232
6233        if (booting) {
6234            finishBooting();
6235        }
6236
6237        if (enableScreen) {
6238            enableScreenAfterBoot();
6239        }
6240    }
6241
6242    @Override
6243    public final void activityResumed(IBinder token) {
6244        final long origId = Binder.clearCallingIdentity();
6245        synchronized(this) {
6246            ActivityStack stack = ActivityRecord.getStackLocked(token);
6247            if (stack != null) {
6248                ActivityRecord.activityResumedLocked(token);
6249            }
6250        }
6251        Binder.restoreCallingIdentity(origId);
6252    }
6253
6254    @Override
6255    public final void activityPaused(IBinder token) {
6256        final long origId = Binder.clearCallingIdentity();
6257        synchronized(this) {
6258            ActivityStack stack = ActivityRecord.getStackLocked(token);
6259            if (stack != null) {
6260                stack.activityPausedLocked(token, false);
6261            }
6262        }
6263        Binder.restoreCallingIdentity(origId);
6264    }
6265
6266    @Override
6267    public final void activityStopped(IBinder token, Bundle icicle,
6268            PersistableBundle persistentState, CharSequence description) {
6269        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6270
6271        // Refuse possible leaked file descriptors
6272        if (icicle != null && icicle.hasFileDescriptors()) {
6273            throw new IllegalArgumentException("File descriptors passed in Bundle");
6274        }
6275
6276        final long origId = Binder.clearCallingIdentity();
6277
6278        synchronized (this) {
6279            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6280            if (r != null) {
6281                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6282            }
6283        }
6284
6285        trimApplications();
6286
6287        Binder.restoreCallingIdentity(origId);
6288    }
6289
6290    @Override
6291    public final void activityDestroyed(IBinder token) {
6292        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6293        synchronized (this) {
6294            ActivityStack stack = ActivityRecord.getStackLocked(token);
6295            if (stack != null) {
6296                stack.activityDestroyedLocked(token);
6297            }
6298        }
6299    }
6300
6301    @Override
6302    public final void backgroundResourcesReleased(IBinder token) {
6303        final long origId = Binder.clearCallingIdentity();
6304        try {
6305            synchronized (this) {
6306                ActivityStack stack = ActivityRecord.getStackLocked(token);
6307                if (stack != null) {
6308                    stack.backgroundResourcesReleased();
6309                }
6310            }
6311        } finally {
6312            Binder.restoreCallingIdentity(origId);
6313        }
6314    }
6315
6316    @Override
6317    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6318        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6319    }
6320
6321    @Override
6322    public final void notifyEnterAnimationComplete(IBinder token) {
6323        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6324    }
6325
6326    @Override
6327    public String getCallingPackage(IBinder token) {
6328        synchronized (this) {
6329            ActivityRecord r = getCallingRecordLocked(token);
6330            return r != null ? r.info.packageName : null;
6331        }
6332    }
6333
6334    @Override
6335    public ComponentName getCallingActivity(IBinder token) {
6336        synchronized (this) {
6337            ActivityRecord r = getCallingRecordLocked(token);
6338            return r != null ? r.intent.getComponent() : null;
6339        }
6340    }
6341
6342    private ActivityRecord getCallingRecordLocked(IBinder token) {
6343        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6344        if (r == null) {
6345            return null;
6346        }
6347        return r.resultTo;
6348    }
6349
6350    @Override
6351    public ComponentName getActivityClassForToken(IBinder token) {
6352        synchronized(this) {
6353            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6354            if (r == null) {
6355                return null;
6356            }
6357            return r.intent.getComponent();
6358        }
6359    }
6360
6361    @Override
6362    public String getPackageForToken(IBinder token) {
6363        synchronized(this) {
6364            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6365            if (r == null) {
6366                return null;
6367            }
6368            return r.packageName;
6369        }
6370    }
6371
6372    @Override
6373    public IIntentSender getIntentSender(int type,
6374            String packageName, IBinder token, String resultWho,
6375            int requestCode, Intent[] intents, String[] resolvedTypes,
6376            int flags, Bundle options, int userId) {
6377        enforceNotIsolatedCaller("getIntentSender");
6378        // Refuse possible leaked file descriptors
6379        if (intents != null) {
6380            if (intents.length < 1) {
6381                throw new IllegalArgumentException("Intents array length must be >= 1");
6382            }
6383            for (int i=0; i<intents.length; i++) {
6384                Intent intent = intents[i];
6385                if (intent != null) {
6386                    if (intent.hasFileDescriptors()) {
6387                        throw new IllegalArgumentException("File descriptors passed in Intent");
6388                    }
6389                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6390                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6391                        throw new IllegalArgumentException(
6392                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6393                    }
6394                    intents[i] = new Intent(intent);
6395                }
6396            }
6397            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6398                throw new IllegalArgumentException(
6399                        "Intent array length does not match resolvedTypes length");
6400            }
6401        }
6402        if (options != null) {
6403            if (options.hasFileDescriptors()) {
6404                throw new IllegalArgumentException("File descriptors passed in options");
6405            }
6406        }
6407
6408        synchronized(this) {
6409            int callingUid = Binder.getCallingUid();
6410            int origUserId = userId;
6411            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6412                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6413                    ALLOW_NON_FULL, "getIntentSender", null);
6414            if (origUserId == UserHandle.USER_CURRENT) {
6415                // We don't want to evaluate this until the pending intent is
6416                // actually executed.  However, we do want to always do the
6417                // security checking for it above.
6418                userId = UserHandle.USER_CURRENT;
6419            }
6420            try {
6421                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6422                    int uid = AppGlobals.getPackageManager()
6423                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6424                    if (!UserHandle.isSameApp(callingUid, uid)) {
6425                        String msg = "Permission Denial: getIntentSender() from pid="
6426                            + Binder.getCallingPid()
6427                            + ", uid=" + Binder.getCallingUid()
6428                            + ", (need uid=" + uid + ")"
6429                            + " is not allowed to send as package " + packageName;
6430                        Slog.w(TAG, msg);
6431                        throw new SecurityException(msg);
6432                    }
6433                }
6434
6435                return getIntentSenderLocked(type, packageName, callingUid, userId,
6436                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6437
6438            } catch (RemoteException e) {
6439                throw new SecurityException(e);
6440            }
6441        }
6442    }
6443
6444    IIntentSender getIntentSenderLocked(int type, String packageName,
6445            int callingUid, int userId, IBinder token, String resultWho,
6446            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6447            Bundle options) {
6448        if (DEBUG_MU)
6449            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6450        ActivityRecord activity = null;
6451        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6452            activity = ActivityRecord.isInStackLocked(token);
6453            if (activity == null) {
6454                return null;
6455            }
6456            if (activity.finishing) {
6457                return null;
6458            }
6459        }
6460
6461        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6462        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6463        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6464        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6465                |PendingIntent.FLAG_UPDATE_CURRENT);
6466
6467        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6468                type, packageName, activity, resultWho,
6469                requestCode, intents, resolvedTypes, flags, options, userId);
6470        WeakReference<PendingIntentRecord> ref;
6471        ref = mIntentSenderRecords.get(key);
6472        PendingIntentRecord rec = ref != null ? ref.get() : null;
6473        if (rec != null) {
6474            if (!cancelCurrent) {
6475                if (updateCurrent) {
6476                    if (rec.key.requestIntent != null) {
6477                        rec.key.requestIntent.replaceExtras(intents != null ?
6478                                intents[intents.length - 1] : null);
6479                    }
6480                    if (intents != null) {
6481                        intents[intents.length-1] = rec.key.requestIntent;
6482                        rec.key.allIntents = intents;
6483                        rec.key.allResolvedTypes = resolvedTypes;
6484                    } else {
6485                        rec.key.allIntents = null;
6486                        rec.key.allResolvedTypes = null;
6487                    }
6488                }
6489                return rec;
6490            }
6491            rec.canceled = true;
6492            mIntentSenderRecords.remove(key);
6493        }
6494        if (noCreate) {
6495            return rec;
6496        }
6497        rec = new PendingIntentRecord(this, key, callingUid);
6498        mIntentSenderRecords.put(key, rec.ref);
6499        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6500            if (activity.pendingResults == null) {
6501                activity.pendingResults
6502                        = new HashSet<WeakReference<PendingIntentRecord>>();
6503            }
6504            activity.pendingResults.add(rec.ref);
6505        }
6506        return rec;
6507    }
6508
6509    @Override
6510    public void cancelIntentSender(IIntentSender sender) {
6511        if (!(sender instanceof PendingIntentRecord)) {
6512            return;
6513        }
6514        synchronized(this) {
6515            PendingIntentRecord rec = (PendingIntentRecord)sender;
6516            try {
6517                int uid = AppGlobals.getPackageManager()
6518                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6519                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6520                    String msg = "Permission Denial: cancelIntentSender() from pid="
6521                        + Binder.getCallingPid()
6522                        + ", uid=" + Binder.getCallingUid()
6523                        + " is not allowed to cancel packges "
6524                        + rec.key.packageName;
6525                    Slog.w(TAG, msg);
6526                    throw new SecurityException(msg);
6527                }
6528            } catch (RemoteException e) {
6529                throw new SecurityException(e);
6530            }
6531            cancelIntentSenderLocked(rec, true);
6532        }
6533    }
6534
6535    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6536        rec.canceled = true;
6537        mIntentSenderRecords.remove(rec.key);
6538        if (cleanActivity && rec.key.activity != null) {
6539            rec.key.activity.pendingResults.remove(rec.ref);
6540        }
6541    }
6542
6543    @Override
6544    public String getPackageForIntentSender(IIntentSender pendingResult) {
6545        if (!(pendingResult instanceof PendingIntentRecord)) {
6546            return null;
6547        }
6548        try {
6549            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6550            return res.key.packageName;
6551        } catch (ClassCastException e) {
6552        }
6553        return null;
6554    }
6555
6556    @Override
6557    public int getUidForIntentSender(IIntentSender sender) {
6558        if (sender instanceof PendingIntentRecord) {
6559            try {
6560                PendingIntentRecord res = (PendingIntentRecord)sender;
6561                return res.uid;
6562            } catch (ClassCastException e) {
6563            }
6564        }
6565        return -1;
6566    }
6567
6568    @Override
6569    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6570        if (!(pendingResult instanceof PendingIntentRecord)) {
6571            return false;
6572        }
6573        try {
6574            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6575            if (res.key.allIntents == null) {
6576                return false;
6577            }
6578            for (int i=0; i<res.key.allIntents.length; i++) {
6579                Intent intent = res.key.allIntents[i];
6580                if (intent.getPackage() != null && intent.getComponent() != null) {
6581                    return false;
6582                }
6583            }
6584            return true;
6585        } catch (ClassCastException e) {
6586        }
6587        return false;
6588    }
6589
6590    @Override
6591    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6592        if (!(pendingResult instanceof PendingIntentRecord)) {
6593            return false;
6594        }
6595        try {
6596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6597            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6598                return true;
6599            }
6600            return false;
6601        } catch (ClassCastException e) {
6602        }
6603        return false;
6604    }
6605
6606    @Override
6607    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6608        if (!(pendingResult instanceof PendingIntentRecord)) {
6609            return null;
6610        }
6611        try {
6612            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6613            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6614        } catch (ClassCastException e) {
6615        }
6616        return null;
6617    }
6618
6619    @Override
6620    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6621        if (!(pendingResult instanceof PendingIntentRecord)) {
6622            return null;
6623        }
6624        try {
6625            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6626            Intent intent = res.key.requestIntent;
6627            if (intent != null) {
6628                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6629                        || res.lastTagPrefix.equals(prefix))) {
6630                    return res.lastTag;
6631                }
6632                res.lastTagPrefix = prefix;
6633                StringBuilder sb = new StringBuilder(128);
6634                if (prefix != null) {
6635                    sb.append(prefix);
6636                }
6637                if (intent.getAction() != null) {
6638                    sb.append(intent.getAction());
6639                } else if (intent.getComponent() != null) {
6640                    intent.getComponent().appendShortString(sb);
6641                } else {
6642                    sb.append("?");
6643                }
6644                return res.lastTag = sb.toString();
6645            }
6646        } catch (ClassCastException e) {
6647        }
6648        return null;
6649    }
6650
6651    @Override
6652    public void setProcessLimit(int max) {
6653        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6654                "setProcessLimit()");
6655        synchronized (this) {
6656            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6657            mProcessLimitOverride = max;
6658        }
6659        trimApplications();
6660    }
6661
6662    @Override
6663    public int getProcessLimit() {
6664        synchronized (this) {
6665            return mProcessLimitOverride;
6666        }
6667    }
6668
6669    void foregroundTokenDied(ForegroundToken token) {
6670        synchronized (ActivityManagerService.this) {
6671            synchronized (mPidsSelfLocked) {
6672                ForegroundToken cur
6673                    = mForegroundProcesses.get(token.pid);
6674                if (cur != token) {
6675                    return;
6676                }
6677                mForegroundProcesses.remove(token.pid);
6678                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6679                if (pr == null) {
6680                    return;
6681                }
6682                pr.forcingToForeground = null;
6683                updateProcessForegroundLocked(pr, false, false);
6684            }
6685            updateOomAdjLocked();
6686        }
6687    }
6688
6689    @Override
6690    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6691        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6692                "setProcessForeground()");
6693        synchronized(this) {
6694            boolean changed = false;
6695
6696            synchronized (mPidsSelfLocked) {
6697                ProcessRecord pr = mPidsSelfLocked.get(pid);
6698                if (pr == null && isForeground) {
6699                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6700                    return;
6701                }
6702                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6703                if (oldToken != null) {
6704                    oldToken.token.unlinkToDeath(oldToken, 0);
6705                    mForegroundProcesses.remove(pid);
6706                    if (pr != null) {
6707                        pr.forcingToForeground = null;
6708                    }
6709                    changed = true;
6710                }
6711                if (isForeground && token != null) {
6712                    ForegroundToken newToken = new ForegroundToken() {
6713                        @Override
6714                        public void binderDied() {
6715                            foregroundTokenDied(this);
6716                        }
6717                    };
6718                    newToken.pid = pid;
6719                    newToken.token = token;
6720                    try {
6721                        token.linkToDeath(newToken, 0);
6722                        mForegroundProcesses.put(pid, newToken);
6723                        pr.forcingToForeground = token;
6724                        changed = true;
6725                    } catch (RemoteException e) {
6726                        // If the process died while doing this, we will later
6727                        // do the cleanup with the process death link.
6728                    }
6729                }
6730            }
6731
6732            if (changed) {
6733                updateOomAdjLocked();
6734            }
6735        }
6736    }
6737
6738    // =========================================================
6739    // PERMISSIONS
6740    // =========================================================
6741
6742    static class PermissionController extends IPermissionController.Stub {
6743        ActivityManagerService mActivityManagerService;
6744        PermissionController(ActivityManagerService activityManagerService) {
6745            mActivityManagerService = activityManagerService;
6746        }
6747
6748        @Override
6749        public boolean checkPermission(String permission, int pid, int uid) {
6750            return mActivityManagerService.checkPermission(permission, pid,
6751                    uid) == PackageManager.PERMISSION_GRANTED;
6752        }
6753    }
6754
6755    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6756        @Override
6757        public int checkComponentPermission(String permission, int pid, int uid,
6758                int owningUid, boolean exported) {
6759            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6760                    owningUid, exported);
6761        }
6762
6763        @Override
6764        public Object getAMSLock() {
6765            return ActivityManagerService.this;
6766        }
6767    }
6768
6769    /**
6770     * This can be called with or without the global lock held.
6771     */
6772    int checkComponentPermission(String permission, int pid, int uid,
6773            int owningUid, boolean exported) {
6774        if (pid == MY_PID) {
6775            return PackageManager.PERMISSION_GRANTED;
6776        }
6777        return ActivityManager.checkComponentPermission(permission, uid,
6778                owningUid, exported);
6779    }
6780
6781    /**
6782     * As the only public entry point for permissions checking, this method
6783     * can enforce the semantic that requesting a check on a null global
6784     * permission is automatically denied.  (Internally a null permission
6785     * string is used when calling {@link #checkComponentPermission} in cases
6786     * when only uid-based security is needed.)
6787     *
6788     * This can be called with or without the global lock held.
6789     */
6790    @Override
6791    public int checkPermission(String permission, int pid, int uid) {
6792        if (permission == null) {
6793            return PackageManager.PERMISSION_DENIED;
6794        }
6795        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6796    }
6797
6798    @Override
6799    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6800        if (permission == null) {
6801            return PackageManager.PERMISSION_DENIED;
6802        }
6803
6804        // We might be performing an operation on behalf of an indirect binder
6805        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6806        // client identity accordingly before proceeding.
6807        Identity tlsIdentity = sCallerIdentity.get();
6808        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6809            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6810                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6811            uid = tlsIdentity.uid;
6812            pid = tlsIdentity.pid;
6813        }
6814
6815        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6816    }
6817
6818    /**
6819     * Binder IPC calls go through the public entry point.
6820     * This can be called with or without the global lock held.
6821     */
6822    int checkCallingPermission(String permission) {
6823        return checkPermission(permission,
6824                Binder.getCallingPid(),
6825                UserHandle.getAppId(Binder.getCallingUid()));
6826    }
6827
6828    /**
6829     * This can be called with or without the global lock held.
6830     */
6831    void enforceCallingPermission(String permission, String func) {
6832        if (checkCallingPermission(permission)
6833                == PackageManager.PERMISSION_GRANTED) {
6834            return;
6835        }
6836
6837        String msg = "Permission Denial: " + func + " from pid="
6838                + Binder.getCallingPid()
6839                + ", uid=" + Binder.getCallingUid()
6840                + " requires " + permission;
6841        Slog.w(TAG, msg);
6842        throw new SecurityException(msg);
6843    }
6844
6845    /**
6846     * Determine if UID is holding permissions required to access {@link Uri} in
6847     * the given {@link ProviderInfo}. Final permission checking is always done
6848     * in {@link ContentProvider}.
6849     */
6850    private final boolean checkHoldingPermissionsLocked(
6851            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6852        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6853                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6854        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6855            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6856                    != PERMISSION_GRANTED) {
6857                return false;
6858            }
6859        }
6860        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6861    }
6862
6863    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6864            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6865        if (pi.applicationInfo.uid == uid) {
6866            return true;
6867        } else if (!pi.exported) {
6868            return false;
6869        }
6870
6871        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6872        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6873        try {
6874            // check if target holds top-level <provider> permissions
6875            if (!readMet && pi.readPermission != null && considerUidPermissions
6876                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6877                readMet = true;
6878            }
6879            if (!writeMet && pi.writePermission != null && considerUidPermissions
6880                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6881                writeMet = true;
6882            }
6883
6884            // track if unprotected read/write is allowed; any denied
6885            // <path-permission> below removes this ability
6886            boolean allowDefaultRead = pi.readPermission == null;
6887            boolean allowDefaultWrite = pi.writePermission == null;
6888
6889            // check if target holds any <path-permission> that match uri
6890            final PathPermission[] pps = pi.pathPermissions;
6891            if (pps != null) {
6892                final String path = grantUri.uri.getPath();
6893                int i = pps.length;
6894                while (i > 0 && (!readMet || !writeMet)) {
6895                    i--;
6896                    PathPermission pp = pps[i];
6897                    if (pp.match(path)) {
6898                        if (!readMet) {
6899                            final String pprperm = pp.getReadPermission();
6900                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6901                                    + pprperm + " for " + pp.getPath()
6902                                    + ": match=" + pp.match(path)
6903                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6904                            if (pprperm != null) {
6905                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6906                                        == PERMISSION_GRANTED) {
6907                                    readMet = true;
6908                                } else {
6909                                    allowDefaultRead = false;
6910                                }
6911                            }
6912                        }
6913                        if (!writeMet) {
6914                            final String ppwperm = pp.getWritePermission();
6915                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6916                                    + ppwperm + " for " + pp.getPath()
6917                                    + ": match=" + pp.match(path)
6918                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6919                            if (ppwperm != null) {
6920                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6921                                        == PERMISSION_GRANTED) {
6922                                    writeMet = true;
6923                                } else {
6924                                    allowDefaultWrite = false;
6925                                }
6926                            }
6927                        }
6928                    }
6929                }
6930            }
6931
6932            // grant unprotected <provider> read/write, if not blocked by
6933            // <path-permission> above
6934            if (allowDefaultRead) readMet = true;
6935            if (allowDefaultWrite) writeMet = true;
6936
6937        } catch (RemoteException e) {
6938            return false;
6939        }
6940
6941        return readMet && writeMet;
6942    }
6943
6944    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6945        ProviderInfo pi = null;
6946        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6947        if (cpr != null) {
6948            pi = cpr.info;
6949        } else {
6950            try {
6951                pi = AppGlobals.getPackageManager().resolveContentProvider(
6952                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6953            } catch (RemoteException ex) {
6954            }
6955        }
6956        return pi;
6957    }
6958
6959    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6960        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6961        if (targetUris != null) {
6962            return targetUris.get(grantUri);
6963        }
6964        return null;
6965    }
6966
6967    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6968            String targetPkg, int targetUid, GrantUri grantUri) {
6969        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6970        if (targetUris == null) {
6971            targetUris = Maps.newArrayMap();
6972            mGrantedUriPermissions.put(targetUid, targetUris);
6973        }
6974
6975        UriPermission perm = targetUris.get(grantUri);
6976        if (perm == null) {
6977            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6978            targetUris.put(grantUri, perm);
6979        }
6980
6981        return perm;
6982    }
6983
6984    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6985            final int modeFlags) {
6986        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6987        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6988                : UriPermission.STRENGTH_OWNED;
6989
6990        // Root gets to do everything.
6991        if (uid == 0) {
6992            return true;
6993        }
6994
6995        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6996        if (perms == null) return false;
6997
6998        // First look for exact match
6999        final UriPermission exactPerm = perms.get(grantUri);
7000        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7001            return true;
7002        }
7003
7004        // No exact match, look for prefixes
7005        final int N = perms.size();
7006        for (int i = 0; i < N; i++) {
7007            final UriPermission perm = perms.valueAt(i);
7008            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7009                    && perm.getStrength(modeFlags) >= minStrength) {
7010                return true;
7011            }
7012        }
7013
7014        return false;
7015    }
7016
7017    /**
7018     * @param uri This uri must NOT contain an embedded userId.
7019     * @param userId The userId in which the uri is to be resolved.
7020     */
7021    @Override
7022    public int checkUriPermission(Uri uri, int pid, int uid,
7023            final int modeFlags, int userId, IBinder callerToken) {
7024        enforceNotIsolatedCaller("checkUriPermission");
7025
7026        // Another redirected-binder-call permissions check as in
7027        // {@link checkPermissionWithToken}.
7028        Identity tlsIdentity = sCallerIdentity.get();
7029        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7030            uid = tlsIdentity.uid;
7031            pid = tlsIdentity.pid;
7032        }
7033
7034        // Our own process gets to do everything.
7035        if (pid == MY_PID) {
7036            return PackageManager.PERMISSION_GRANTED;
7037        }
7038        synchronized (this) {
7039            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7040                    ? PackageManager.PERMISSION_GRANTED
7041                    : PackageManager.PERMISSION_DENIED;
7042        }
7043    }
7044
7045    /**
7046     * Check if the targetPkg can be granted permission to access uri by
7047     * the callingUid using the given modeFlags.  Throws a security exception
7048     * if callingUid is not allowed to do this.  Returns the uid of the target
7049     * if the URI permission grant should be performed; returns -1 if it is not
7050     * needed (for example targetPkg already has permission to access the URI).
7051     * If you already know the uid of the target, you can supply it in
7052     * lastTargetUid else set that to -1.
7053     */
7054    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7055            final int modeFlags, int lastTargetUid) {
7056        if (!Intent.isAccessUriMode(modeFlags)) {
7057            return -1;
7058        }
7059
7060        if (targetPkg != null) {
7061            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7062                    "Checking grant " + targetPkg + " permission to " + grantUri);
7063        }
7064
7065        final IPackageManager pm = AppGlobals.getPackageManager();
7066
7067        // If this is not a content: uri, we can't do anything with it.
7068        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7069            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7070                    "Can't grant URI permission for non-content URI: " + grantUri);
7071            return -1;
7072        }
7073
7074        final String authority = grantUri.uri.getAuthority();
7075        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7076        if (pi == null) {
7077            Slog.w(TAG, "No content provider found for permission check: " +
7078                    grantUri.uri.toSafeString());
7079            return -1;
7080        }
7081
7082        int targetUid = lastTargetUid;
7083        if (targetUid < 0 && targetPkg != null) {
7084            try {
7085                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7086                if (targetUid < 0) {
7087                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7088                            "Can't grant URI permission no uid for: " + targetPkg);
7089                    return -1;
7090                }
7091            } catch (RemoteException ex) {
7092                return -1;
7093            }
7094        }
7095
7096        if (targetUid >= 0) {
7097            // First...  does the target actually need this permission?
7098            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7099                // No need to grant the target this permission.
7100                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7101                        "Target " + targetPkg + " already has full permission to " + grantUri);
7102                return -1;
7103            }
7104        } else {
7105            // First...  there is no target package, so can anyone access it?
7106            boolean allowed = pi.exported;
7107            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7108                if (pi.readPermission != null) {
7109                    allowed = false;
7110                }
7111            }
7112            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7113                if (pi.writePermission != null) {
7114                    allowed = false;
7115                }
7116            }
7117            if (allowed) {
7118                return -1;
7119            }
7120        }
7121
7122        /* There is a special cross user grant if:
7123         * - The target is on another user.
7124         * - Apps on the current user can access the uri without any uid permissions.
7125         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7126         * grant uri permissions.
7127         */
7128        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7129                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7130                modeFlags, false /*without considering the uid permissions*/);
7131
7132        // Second...  is the provider allowing granting of URI permissions?
7133        if (!specialCrossUserGrant) {
7134            if (!pi.grantUriPermissions) {
7135                throw new SecurityException("Provider " + pi.packageName
7136                        + "/" + pi.name
7137                        + " does not allow granting of Uri permissions (uri "
7138                        + grantUri + ")");
7139            }
7140            if (pi.uriPermissionPatterns != null) {
7141                final int N = pi.uriPermissionPatterns.length;
7142                boolean allowed = false;
7143                for (int i=0; i<N; i++) {
7144                    if (pi.uriPermissionPatterns[i] != null
7145                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7146                        allowed = true;
7147                        break;
7148                    }
7149                }
7150                if (!allowed) {
7151                    throw new SecurityException("Provider " + pi.packageName
7152                            + "/" + pi.name
7153                            + " does not allow granting of permission to path of Uri "
7154                            + grantUri);
7155                }
7156            }
7157        }
7158
7159        // Third...  does the caller itself have permission to access
7160        // this uri?
7161        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7162            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7163                // Require they hold a strong enough Uri permission
7164                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7165                    throw new SecurityException("Uid " + callingUid
7166                            + " does not have permission to uri " + grantUri);
7167                }
7168            }
7169        }
7170        return targetUid;
7171    }
7172
7173    /**
7174     * @param uri This uri must NOT contain an embedded userId.
7175     * @param userId The userId in which the uri is to be resolved.
7176     */
7177    @Override
7178    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7179            final int modeFlags, int userId) {
7180        enforceNotIsolatedCaller("checkGrantUriPermission");
7181        synchronized(this) {
7182            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7183                    new GrantUri(userId, uri, false), modeFlags, -1);
7184        }
7185    }
7186
7187    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7188            final int modeFlags, UriPermissionOwner owner) {
7189        if (!Intent.isAccessUriMode(modeFlags)) {
7190            return;
7191        }
7192
7193        // So here we are: the caller has the assumed permission
7194        // to the uri, and the target doesn't.  Let's now give this to
7195        // the target.
7196
7197        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7198                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7199
7200        final String authority = grantUri.uri.getAuthority();
7201        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7202        if (pi == null) {
7203            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7204            return;
7205        }
7206
7207        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7208            grantUri.prefix = true;
7209        }
7210        final UriPermission perm = findOrCreateUriPermissionLocked(
7211                pi.packageName, targetPkg, targetUid, grantUri);
7212        perm.grantModes(modeFlags, owner);
7213    }
7214
7215    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7216            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7217        if (targetPkg == null) {
7218            throw new NullPointerException("targetPkg");
7219        }
7220        int targetUid;
7221        final IPackageManager pm = AppGlobals.getPackageManager();
7222        try {
7223            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7224        } catch (RemoteException ex) {
7225            return;
7226        }
7227
7228        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7229                targetUid);
7230        if (targetUid < 0) {
7231            return;
7232        }
7233
7234        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7235                owner);
7236    }
7237
7238    static class NeededUriGrants extends ArrayList<GrantUri> {
7239        final String targetPkg;
7240        final int targetUid;
7241        final int flags;
7242
7243        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7244            this.targetPkg = targetPkg;
7245            this.targetUid = targetUid;
7246            this.flags = flags;
7247        }
7248    }
7249
7250    /**
7251     * Like checkGrantUriPermissionLocked, but takes an Intent.
7252     */
7253    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7254            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7255        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7256                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7257                + " clip=" + (intent != null ? intent.getClipData() : null)
7258                + " from " + intent + "; flags=0x"
7259                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7260
7261        if (targetPkg == null) {
7262            throw new NullPointerException("targetPkg");
7263        }
7264
7265        if (intent == null) {
7266            return null;
7267        }
7268        Uri data = intent.getData();
7269        ClipData clip = intent.getClipData();
7270        if (data == null && clip == null) {
7271            return null;
7272        }
7273        // Default userId for uris in the intent (if they don't specify it themselves)
7274        int contentUserHint = intent.getContentUserHint();
7275        if (contentUserHint == UserHandle.USER_CURRENT) {
7276            contentUserHint = UserHandle.getUserId(callingUid);
7277        }
7278        final IPackageManager pm = AppGlobals.getPackageManager();
7279        int targetUid;
7280        if (needed != null) {
7281            targetUid = needed.targetUid;
7282        } else {
7283            try {
7284                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7285            } catch (RemoteException ex) {
7286                return null;
7287            }
7288            if (targetUid < 0) {
7289                if (DEBUG_URI_PERMISSION) {
7290                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7291                            + " on user " + targetUserId);
7292                }
7293                return null;
7294            }
7295        }
7296        if (data != null) {
7297            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7298            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7299                    targetUid);
7300            if (targetUid > 0) {
7301                if (needed == null) {
7302                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7303                }
7304                needed.add(grantUri);
7305            }
7306        }
7307        if (clip != null) {
7308            for (int i=0; i<clip.getItemCount(); i++) {
7309                Uri uri = clip.getItemAt(i).getUri();
7310                if (uri != null) {
7311                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7312                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7313                            targetUid);
7314                    if (targetUid > 0) {
7315                        if (needed == null) {
7316                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7317                        }
7318                        needed.add(grantUri);
7319                    }
7320                } else {
7321                    Intent clipIntent = clip.getItemAt(i).getIntent();
7322                    if (clipIntent != null) {
7323                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7324                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7325                        if (newNeeded != null) {
7326                            needed = newNeeded;
7327                        }
7328                    }
7329                }
7330            }
7331        }
7332
7333        return needed;
7334    }
7335
7336    /**
7337     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7338     */
7339    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7340            UriPermissionOwner owner) {
7341        if (needed != null) {
7342            for (int i=0; i<needed.size(); i++) {
7343                GrantUri grantUri = needed.get(i);
7344                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7345                        grantUri, needed.flags, owner);
7346            }
7347        }
7348    }
7349
7350    void grantUriPermissionFromIntentLocked(int callingUid,
7351            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7352        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7353                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7354        if (needed == null) {
7355            return;
7356        }
7357
7358        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7359    }
7360
7361    /**
7362     * @param uri This uri must NOT contain an embedded userId.
7363     * @param userId The userId in which the uri is to be resolved.
7364     */
7365    @Override
7366    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7367            final int modeFlags, int userId) {
7368        enforceNotIsolatedCaller("grantUriPermission");
7369        GrantUri grantUri = new GrantUri(userId, uri, false);
7370        synchronized(this) {
7371            final ProcessRecord r = getRecordForAppLocked(caller);
7372            if (r == null) {
7373                throw new SecurityException("Unable to find app for caller "
7374                        + caller
7375                        + " when granting permission to uri " + grantUri);
7376            }
7377            if (targetPkg == null) {
7378                throw new IllegalArgumentException("null target");
7379            }
7380            if (grantUri == null) {
7381                throw new IllegalArgumentException("null uri");
7382            }
7383
7384            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7385                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7386                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7387                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7388
7389            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7390                    UserHandle.getUserId(r.uid));
7391        }
7392    }
7393
7394    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7395        if (perm.modeFlags == 0) {
7396            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7397                    perm.targetUid);
7398            if (perms != null) {
7399                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7400                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7401
7402                perms.remove(perm.uri);
7403                if (perms.isEmpty()) {
7404                    mGrantedUriPermissions.remove(perm.targetUid);
7405                }
7406            }
7407        }
7408    }
7409
7410    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7411        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7412
7413        final IPackageManager pm = AppGlobals.getPackageManager();
7414        final String authority = grantUri.uri.getAuthority();
7415        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7416        if (pi == null) {
7417            Slog.w(TAG, "No content provider found for permission revoke: "
7418                    + grantUri.toSafeString());
7419            return;
7420        }
7421
7422        // Does the caller have this permission on the URI?
7423        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7424            // If they don't have direct access to the URI, then revoke any
7425            // ownerless URI permissions that have been granted to them.
7426            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7427            if (perms != null) {
7428                boolean persistChanged = false;
7429                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7430                    final UriPermission perm = it.next();
7431                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7432                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7433                        if (DEBUG_URI_PERMISSION)
7434                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7435                                    " permission to " + perm.uri);
7436                        persistChanged |= perm.revokeModes(
7437                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7438                        if (perm.modeFlags == 0) {
7439                            it.remove();
7440                        }
7441                    }
7442                }
7443                if (perms.isEmpty()) {
7444                    mGrantedUriPermissions.remove(callingUid);
7445                }
7446                if (persistChanged) {
7447                    schedulePersistUriGrants();
7448                }
7449            }
7450            return;
7451        }
7452
7453        boolean persistChanged = false;
7454
7455        // Go through all of the permissions and remove any that match.
7456        int N = mGrantedUriPermissions.size();
7457        for (int i = 0; i < N; i++) {
7458            final int targetUid = mGrantedUriPermissions.keyAt(i);
7459            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7460
7461            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7462                final UriPermission perm = it.next();
7463                if (perm.uri.sourceUserId == grantUri.sourceUserId
7464                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7465                    if (DEBUG_URI_PERMISSION)
7466                        Slog.v(TAG,
7467                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7468                    persistChanged |= perm.revokeModes(
7469                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7470                    if (perm.modeFlags == 0) {
7471                        it.remove();
7472                    }
7473                }
7474            }
7475
7476            if (perms.isEmpty()) {
7477                mGrantedUriPermissions.remove(targetUid);
7478                N--;
7479                i--;
7480            }
7481        }
7482
7483        if (persistChanged) {
7484            schedulePersistUriGrants();
7485        }
7486    }
7487
7488    /**
7489     * @param uri This uri must NOT contain an embedded userId.
7490     * @param userId The userId in which the uri is to be resolved.
7491     */
7492    @Override
7493    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7494            int userId) {
7495        enforceNotIsolatedCaller("revokeUriPermission");
7496        synchronized(this) {
7497            final ProcessRecord r = getRecordForAppLocked(caller);
7498            if (r == null) {
7499                throw new SecurityException("Unable to find app for caller "
7500                        + caller
7501                        + " when revoking permission to uri " + uri);
7502            }
7503            if (uri == null) {
7504                Slog.w(TAG, "revokeUriPermission: null uri");
7505                return;
7506            }
7507
7508            if (!Intent.isAccessUriMode(modeFlags)) {
7509                return;
7510            }
7511
7512            final IPackageManager pm = AppGlobals.getPackageManager();
7513            final String authority = uri.getAuthority();
7514            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7515            if (pi == null) {
7516                Slog.w(TAG, "No content provider found for permission revoke: "
7517                        + uri.toSafeString());
7518                return;
7519            }
7520
7521            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7522        }
7523    }
7524
7525    /**
7526     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7527     * given package.
7528     *
7529     * @param packageName Package name to match, or {@code null} to apply to all
7530     *            packages.
7531     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7532     *            to all users.
7533     * @param persistable If persistable grants should be removed.
7534     */
7535    private void removeUriPermissionsForPackageLocked(
7536            String packageName, int userHandle, boolean persistable) {
7537        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7538            throw new IllegalArgumentException("Must narrow by either package or user");
7539        }
7540
7541        boolean persistChanged = false;
7542
7543        int N = mGrantedUriPermissions.size();
7544        for (int i = 0; i < N; i++) {
7545            final int targetUid = mGrantedUriPermissions.keyAt(i);
7546            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7547
7548            // Only inspect grants matching user
7549            if (userHandle == UserHandle.USER_ALL
7550                    || userHandle == UserHandle.getUserId(targetUid)) {
7551                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7552                    final UriPermission perm = it.next();
7553
7554                    // Only inspect grants matching package
7555                    if (packageName == null || perm.sourcePkg.equals(packageName)
7556                            || perm.targetPkg.equals(packageName)) {
7557                        persistChanged |= perm.revokeModes(persistable
7558                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7559
7560                        // Only remove when no modes remain; any persisted grants
7561                        // will keep this alive.
7562                        if (perm.modeFlags == 0) {
7563                            it.remove();
7564                        }
7565                    }
7566                }
7567
7568                if (perms.isEmpty()) {
7569                    mGrantedUriPermissions.remove(targetUid);
7570                    N--;
7571                    i--;
7572                }
7573            }
7574        }
7575
7576        if (persistChanged) {
7577            schedulePersistUriGrants();
7578        }
7579    }
7580
7581    @Override
7582    public IBinder newUriPermissionOwner(String name) {
7583        enforceNotIsolatedCaller("newUriPermissionOwner");
7584        synchronized(this) {
7585            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7586            return owner.getExternalTokenLocked();
7587        }
7588    }
7589
7590    /**
7591     * @param uri This uri must NOT contain an embedded userId.
7592     * @param sourceUserId The userId in which the uri is to be resolved.
7593     * @param targetUserId The userId of the app that receives the grant.
7594     */
7595    @Override
7596    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7597            final int modeFlags, int sourceUserId, int targetUserId) {
7598        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7599                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7600        synchronized(this) {
7601            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7602            if (owner == null) {
7603                throw new IllegalArgumentException("Unknown owner: " + token);
7604            }
7605            if (fromUid != Binder.getCallingUid()) {
7606                if (Binder.getCallingUid() != Process.myUid()) {
7607                    // Only system code can grant URI permissions on behalf
7608                    // of other users.
7609                    throw new SecurityException("nice try");
7610                }
7611            }
7612            if (targetPkg == null) {
7613                throw new IllegalArgumentException("null target");
7614            }
7615            if (uri == null) {
7616                throw new IllegalArgumentException("null uri");
7617            }
7618
7619            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7620                    modeFlags, owner, targetUserId);
7621        }
7622    }
7623
7624    /**
7625     * @param uri This uri must NOT contain an embedded userId.
7626     * @param userId The userId in which the uri is to be resolved.
7627     */
7628    @Override
7629    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7630        synchronized(this) {
7631            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7632            if (owner == null) {
7633                throw new IllegalArgumentException("Unknown owner: " + token);
7634            }
7635
7636            if (uri == null) {
7637                owner.removeUriPermissionsLocked(mode);
7638            } else {
7639                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7640            }
7641        }
7642    }
7643
7644    private void schedulePersistUriGrants() {
7645        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7646            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7647                    10 * DateUtils.SECOND_IN_MILLIS);
7648        }
7649    }
7650
7651    private void writeGrantedUriPermissions() {
7652        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7653
7654        // Snapshot permissions so we can persist without lock
7655        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7656        synchronized (this) {
7657            final int size = mGrantedUriPermissions.size();
7658            for (int i = 0; i < size; i++) {
7659                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7660                for (UriPermission perm : perms.values()) {
7661                    if (perm.persistedModeFlags != 0) {
7662                        persist.add(perm.snapshot());
7663                    }
7664                }
7665            }
7666        }
7667
7668        FileOutputStream fos = null;
7669        try {
7670            fos = mGrantFile.startWrite();
7671
7672            XmlSerializer out = new FastXmlSerializer();
7673            out.setOutput(fos, "utf-8");
7674            out.startDocument(null, true);
7675            out.startTag(null, TAG_URI_GRANTS);
7676            for (UriPermission.Snapshot perm : persist) {
7677                out.startTag(null, TAG_URI_GRANT);
7678                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7679                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7680                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7681                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7682                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7683                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7684                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7685                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7686                out.endTag(null, TAG_URI_GRANT);
7687            }
7688            out.endTag(null, TAG_URI_GRANTS);
7689            out.endDocument();
7690
7691            mGrantFile.finishWrite(fos);
7692        } catch (IOException e) {
7693            if (fos != null) {
7694                mGrantFile.failWrite(fos);
7695            }
7696        }
7697    }
7698
7699    private void readGrantedUriPermissionsLocked() {
7700        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7701
7702        final long now = System.currentTimeMillis();
7703
7704        FileInputStream fis = null;
7705        try {
7706            fis = mGrantFile.openRead();
7707            final XmlPullParser in = Xml.newPullParser();
7708            in.setInput(fis, null);
7709
7710            int type;
7711            while ((type = in.next()) != END_DOCUMENT) {
7712                final String tag = in.getName();
7713                if (type == START_TAG) {
7714                    if (TAG_URI_GRANT.equals(tag)) {
7715                        final int sourceUserId;
7716                        final int targetUserId;
7717                        final int userHandle = readIntAttribute(in,
7718                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7719                        if (userHandle != UserHandle.USER_NULL) {
7720                            // For backwards compatibility.
7721                            sourceUserId = userHandle;
7722                            targetUserId = userHandle;
7723                        } else {
7724                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7725                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7726                        }
7727                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7728                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7729                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7730                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7731                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7732                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7733
7734                        // Sanity check that provider still belongs to source package
7735                        final ProviderInfo pi = getProviderInfoLocked(
7736                                uri.getAuthority(), sourceUserId);
7737                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7738                            int targetUid = -1;
7739                            try {
7740                                targetUid = AppGlobals.getPackageManager()
7741                                        .getPackageUid(targetPkg, targetUserId);
7742                            } catch (RemoteException e) {
7743                            }
7744                            if (targetUid != -1) {
7745                                final UriPermission perm = findOrCreateUriPermissionLocked(
7746                                        sourcePkg, targetPkg, targetUid,
7747                                        new GrantUri(sourceUserId, uri, prefix));
7748                                perm.initPersistedModes(modeFlags, createdTime);
7749                            }
7750                        } else {
7751                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7752                                    + " but instead found " + pi);
7753                        }
7754                    }
7755                }
7756            }
7757        } catch (FileNotFoundException e) {
7758            // Missing grants is okay
7759        } catch (IOException e) {
7760            Slog.wtf(TAG, "Failed reading Uri grants", e);
7761        } catch (XmlPullParserException e) {
7762            Slog.wtf(TAG, "Failed reading Uri grants", e);
7763        } finally {
7764            IoUtils.closeQuietly(fis);
7765        }
7766    }
7767
7768    /**
7769     * @param uri This uri must NOT contain an embedded userId.
7770     * @param userId The userId in which the uri is to be resolved.
7771     */
7772    @Override
7773    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7774        enforceNotIsolatedCaller("takePersistableUriPermission");
7775
7776        Preconditions.checkFlagsArgument(modeFlags,
7777                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7778
7779        synchronized (this) {
7780            final int callingUid = Binder.getCallingUid();
7781            boolean persistChanged = false;
7782            GrantUri grantUri = new GrantUri(userId, uri, false);
7783
7784            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7785                    new GrantUri(userId, uri, false));
7786            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7787                    new GrantUri(userId, uri, true));
7788
7789            final boolean exactValid = (exactPerm != null)
7790                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7791            final boolean prefixValid = (prefixPerm != null)
7792                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7793
7794            if (!(exactValid || prefixValid)) {
7795                throw new SecurityException("No persistable permission grants found for UID "
7796                        + callingUid + " and Uri " + grantUri.toSafeString());
7797            }
7798
7799            if (exactValid) {
7800                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7801            }
7802            if (prefixValid) {
7803                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7804            }
7805
7806            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7807
7808            if (persistChanged) {
7809                schedulePersistUriGrants();
7810            }
7811        }
7812    }
7813
7814    /**
7815     * @param uri This uri must NOT contain an embedded userId.
7816     * @param userId The userId in which the uri is to be resolved.
7817     */
7818    @Override
7819    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7820        enforceNotIsolatedCaller("releasePersistableUriPermission");
7821
7822        Preconditions.checkFlagsArgument(modeFlags,
7823                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7824
7825        synchronized (this) {
7826            final int callingUid = Binder.getCallingUid();
7827            boolean persistChanged = false;
7828
7829            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7830                    new GrantUri(userId, uri, false));
7831            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7832                    new GrantUri(userId, uri, true));
7833            if (exactPerm == null && prefixPerm == null) {
7834                throw new SecurityException("No permission grants found for UID " + callingUid
7835                        + " and Uri " + uri.toSafeString());
7836            }
7837
7838            if (exactPerm != null) {
7839                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7840                removeUriPermissionIfNeededLocked(exactPerm);
7841            }
7842            if (prefixPerm != null) {
7843                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7844                removeUriPermissionIfNeededLocked(prefixPerm);
7845            }
7846
7847            if (persistChanged) {
7848                schedulePersistUriGrants();
7849            }
7850        }
7851    }
7852
7853    /**
7854     * Prune any older {@link UriPermission} for the given UID until outstanding
7855     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7856     *
7857     * @return if any mutations occured that require persisting.
7858     */
7859    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7860        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7861        if (perms == null) return false;
7862        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7863
7864        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7865        for (UriPermission perm : perms.values()) {
7866            if (perm.persistedModeFlags != 0) {
7867                persisted.add(perm);
7868            }
7869        }
7870
7871        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7872        if (trimCount <= 0) return false;
7873
7874        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7875        for (int i = 0; i < trimCount; i++) {
7876            final UriPermission perm = persisted.get(i);
7877
7878            if (DEBUG_URI_PERMISSION) {
7879                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7880            }
7881
7882            perm.releasePersistableModes(~0);
7883            removeUriPermissionIfNeededLocked(perm);
7884        }
7885
7886        return true;
7887    }
7888
7889    @Override
7890    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7891            String packageName, boolean incoming) {
7892        enforceNotIsolatedCaller("getPersistedUriPermissions");
7893        Preconditions.checkNotNull(packageName, "packageName");
7894
7895        final int callingUid = Binder.getCallingUid();
7896        final IPackageManager pm = AppGlobals.getPackageManager();
7897        try {
7898            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7899            if (packageUid != callingUid) {
7900                throw new SecurityException(
7901                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7902            }
7903        } catch (RemoteException e) {
7904            throw new SecurityException("Failed to verify package name ownership");
7905        }
7906
7907        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7908        synchronized (this) {
7909            if (incoming) {
7910                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7911                        callingUid);
7912                if (perms == null) {
7913                    Slog.w(TAG, "No permission grants found for " + packageName);
7914                } else {
7915                    for (UriPermission perm : perms.values()) {
7916                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7917                            result.add(perm.buildPersistedPublicApiObject());
7918                        }
7919                    }
7920                }
7921            } else {
7922                final int size = mGrantedUriPermissions.size();
7923                for (int i = 0; i < size; i++) {
7924                    final ArrayMap<GrantUri, UriPermission> perms =
7925                            mGrantedUriPermissions.valueAt(i);
7926                    for (UriPermission perm : perms.values()) {
7927                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7928                            result.add(perm.buildPersistedPublicApiObject());
7929                        }
7930                    }
7931                }
7932            }
7933        }
7934        return new ParceledListSlice<android.content.UriPermission>(result);
7935    }
7936
7937    @Override
7938    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7939        synchronized (this) {
7940            ProcessRecord app =
7941                who != null ? getRecordForAppLocked(who) : null;
7942            if (app == null) return;
7943
7944            Message msg = Message.obtain();
7945            msg.what = WAIT_FOR_DEBUGGER_MSG;
7946            msg.obj = app;
7947            msg.arg1 = waiting ? 1 : 0;
7948            mHandler.sendMessage(msg);
7949        }
7950    }
7951
7952    @Override
7953    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7954        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7955        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7956        outInfo.availMem = Process.getFreeMemory();
7957        outInfo.totalMem = Process.getTotalMemory();
7958        outInfo.threshold = homeAppMem;
7959        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7960        outInfo.hiddenAppThreshold = cachedAppMem;
7961        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7962                ProcessList.SERVICE_ADJ);
7963        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7964                ProcessList.VISIBLE_APP_ADJ);
7965        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7966                ProcessList.FOREGROUND_APP_ADJ);
7967    }
7968
7969    // =========================================================
7970    // TASK MANAGEMENT
7971    // =========================================================
7972
7973    @Override
7974    public List<IAppTask> getAppTasks(String callingPackage) {
7975        int callingUid = Binder.getCallingUid();
7976        long ident = Binder.clearCallingIdentity();
7977
7978        synchronized(this) {
7979            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7980            try {
7981                if (localLOGV) Slog.v(TAG, "getAppTasks");
7982
7983                final int N = mRecentTasks.size();
7984                for (int i = 0; i < N; i++) {
7985                    TaskRecord tr = mRecentTasks.get(i);
7986                    // Skip tasks that do not match the caller.  We don't need to verify
7987                    // callingPackage, because we are also limiting to callingUid and know
7988                    // that will limit to the correct security sandbox.
7989                    if (tr.effectiveUid != callingUid) {
7990                        continue;
7991                    }
7992                    Intent intent = tr.getBaseIntent();
7993                    if (intent == null ||
7994                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7995                        continue;
7996                    }
7997                    ActivityManager.RecentTaskInfo taskInfo =
7998                            createRecentTaskInfoFromTaskRecord(tr);
7999                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8000                    list.add(taskImpl);
8001                }
8002            } finally {
8003                Binder.restoreCallingIdentity(ident);
8004            }
8005            return list;
8006        }
8007    }
8008
8009    @Override
8010    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8011        final int callingUid = Binder.getCallingUid();
8012        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8013
8014        synchronized(this) {
8015            if (localLOGV) Slog.v(
8016                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8017
8018            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8019                    callingUid);
8020
8021            // TODO: Improve with MRU list from all ActivityStacks.
8022            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8023        }
8024
8025        return list;
8026    }
8027
8028    /**
8029     * Creates a new RecentTaskInfo from a TaskRecord.
8030     */
8031    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8032        // Update the task description to reflect any changes in the task stack
8033        tr.updateTaskDescription();
8034
8035        // Compose the recent task info
8036        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8037        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8038        rti.persistentId = tr.taskId;
8039        rti.baseIntent = new Intent(tr.getBaseIntent());
8040        rti.origActivity = tr.origActivity;
8041        rti.description = tr.lastDescription;
8042        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8043        rti.userId = tr.userId;
8044        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8045        rti.firstActiveTime = tr.firstActiveTime;
8046        rti.lastActiveTime = tr.lastActiveTime;
8047        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8048        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8049        return rti;
8050    }
8051
8052    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8053        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8054                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8055        if (!allowed) {
8056            if (checkPermission(android.Manifest.permission.GET_TASKS,
8057                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8058                // Temporary compatibility: some existing apps on the system image may
8059                // still be requesting the old permission and not switched to the new
8060                // one; if so, we'll still allow them full access.  This means we need
8061                // to see if they are holding the old permission and are a system app.
8062                try {
8063                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8064                        allowed = true;
8065                        Slog.w(TAG, caller + ": caller " + callingUid
8066                                + " is using old GET_TASKS but privileged; allowing");
8067                    }
8068                } catch (RemoteException e) {
8069                }
8070            }
8071        }
8072        if (!allowed) {
8073            Slog.w(TAG, caller + ": caller " + callingUid
8074                    + " does not hold GET_TASKS; limiting output");
8075        }
8076        return allowed;
8077    }
8078
8079    @Override
8080    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8081        final int callingUid = Binder.getCallingUid();
8082        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8083                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8084
8085        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8086        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8087        synchronized (this) {
8088            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8089                    callingUid);
8090            final boolean detailed = checkCallingPermission(
8091                    android.Manifest.permission.GET_DETAILED_TASKS)
8092                    == PackageManager.PERMISSION_GRANTED;
8093
8094            final int N = mRecentTasks.size();
8095            ArrayList<ActivityManager.RecentTaskInfo> res
8096                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8097                            maxNum < N ? maxNum : N);
8098
8099            final Set<Integer> includedUsers;
8100            if (includeProfiles) {
8101                includedUsers = getProfileIdsLocked(userId);
8102            } else {
8103                includedUsers = new HashSet<Integer>();
8104            }
8105            includedUsers.add(Integer.valueOf(userId));
8106
8107            for (int i=0; i<N && maxNum > 0; i++) {
8108                TaskRecord tr = mRecentTasks.get(i);
8109                // Only add calling user or related users recent tasks
8110                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8111                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8112                    continue;
8113                }
8114
8115                // Return the entry if desired by the caller.  We always return
8116                // the first entry, because callers always expect this to be the
8117                // foreground app.  We may filter others if the caller has
8118                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8119                // we should exclude the entry.
8120
8121                if (i == 0
8122                        || withExcluded
8123                        || (tr.intent == null)
8124                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8125                                == 0)) {
8126                    if (!allowed) {
8127                        // If the caller doesn't have the GET_TASKS permission, then only
8128                        // allow them to see a small subset of tasks -- their own and home.
8129                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8130                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8131                            continue;
8132                        }
8133                    }
8134                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8135                        if (tr.stack != null && tr.stack.isHomeStack()) {
8136                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8137                            continue;
8138                        }
8139                    }
8140                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8141                        // Don't include auto remove tasks that are finished or finishing.
8142                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8143                                + tr);
8144                        continue;
8145                    }
8146                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8147                            && !tr.isAvailable) {
8148                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8149                        continue;
8150                    }
8151
8152                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8153                    if (!detailed) {
8154                        rti.baseIntent.replaceExtras((Bundle)null);
8155                    }
8156
8157                    res.add(rti);
8158                    maxNum--;
8159                }
8160            }
8161            return res;
8162        }
8163    }
8164
8165    private TaskRecord taskForIdLocked(int id) {
8166        final TaskRecord task = recentTaskForIdLocked(id);
8167        if (task != null) {
8168            return task;
8169        }
8170
8171        // Don't give up. Sometimes it just hasn't made it to recents yet.
8172        return mStackSupervisor.anyTaskForIdLocked(id);
8173    }
8174
8175    private TaskRecord recentTaskForIdLocked(int id) {
8176        final int N = mRecentTasks.size();
8177            for (int i=0; i<N; i++) {
8178                TaskRecord tr = mRecentTasks.get(i);
8179                if (tr.taskId == id) {
8180                    return tr;
8181                }
8182            }
8183            return null;
8184    }
8185
8186    @Override
8187    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8188        synchronized (this) {
8189            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8190                    "getTaskThumbnail()");
8191            TaskRecord tr = recentTaskForIdLocked(id);
8192            if (tr != null) {
8193                return tr.getTaskThumbnailLocked();
8194            }
8195        }
8196        return null;
8197    }
8198
8199    @Override
8200    public int addAppTask(IBinder activityToken, Intent intent,
8201            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8202        final int callingUid = Binder.getCallingUid();
8203        final long callingIdent = Binder.clearCallingIdentity();
8204
8205        try {
8206            synchronized (this) {
8207                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8208                if (r == null) {
8209                    throw new IllegalArgumentException("Activity does not exist; token="
8210                            + activityToken);
8211                }
8212                ComponentName comp = intent.getComponent();
8213                if (comp == null) {
8214                    throw new IllegalArgumentException("Intent " + intent
8215                            + " must specify explicit component");
8216                }
8217                if (thumbnail.getWidth() != mThumbnailWidth
8218                        || thumbnail.getHeight() != mThumbnailHeight) {
8219                    throw new IllegalArgumentException("Bad thumbnail size: got "
8220                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8221                            + mThumbnailWidth + "x" + mThumbnailHeight);
8222                }
8223                if (intent.getSelector() != null) {
8224                    intent.setSelector(null);
8225                }
8226                if (intent.getSourceBounds() != null) {
8227                    intent.setSourceBounds(null);
8228                }
8229                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8230                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8231                        // The caller has added this as an auto-remove task...  that makes no
8232                        // sense, so turn off auto-remove.
8233                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8234                    }
8235                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8236                    // Must be a new task.
8237                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8238                }
8239                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8240                    mLastAddedTaskActivity = null;
8241                }
8242                ActivityInfo ainfo = mLastAddedTaskActivity;
8243                if (ainfo == null) {
8244                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8245                            comp, 0, UserHandle.getUserId(callingUid));
8246                    if (ainfo.applicationInfo.uid != callingUid) {
8247                        throw new SecurityException(
8248                                "Can't add task for another application: target uid="
8249                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8250                    }
8251                }
8252
8253                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8254                        intent, description);
8255
8256                int trimIdx = trimRecentsForTaskLocked(task, false);
8257                if (trimIdx >= 0) {
8258                    // If this would have caused a trim, then we'll abort because that
8259                    // means it would be added at the end of the list but then just removed.
8260                    return -1;
8261                }
8262
8263                final int N = mRecentTasks.size();
8264                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8265                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8266                    tr.removedFromRecents();
8267                }
8268
8269                task.inRecents = true;
8270                mRecentTasks.add(task);
8271                r.task.stack.addTask(task, false, false);
8272
8273                task.setLastThumbnail(thumbnail);
8274                task.freeLastThumbnail();
8275
8276                return task.taskId;
8277            }
8278        } finally {
8279            Binder.restoreCallingIdentity(callingIdent);
8280        }
8281    }
8282
8283    @Override
8284    public Point getAppTaskThumbnailSize() {
8285        synchronized (this) {
8286            return new Point(mThumbnailWidth,  mThumbnailHeight);
8287        }
8288    }
8289
8290    @Override
8291    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8292        synchronized (this) {
8293            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8294            if (r != null) {
8295                r.setTaskDescription(td);
8296                r.task.updateTaskDescription();
8297            }
8298        }
8299    }
8300
8301    @Override
8302    public Bitmap getTaskDescriptionIcon(String filename) {
8303        if (!FileUtils.isValidExtFilename(filename)
8304                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8305            throw new IllegalArgumentException("Bad filename: " + filename);
8306        }
8307        return mTaskPersister.getTaskDescriptionIcon(filename);
8308    }
8309
8310    @Override
8311    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8312            throws RemoteException {
8313        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8314                opts.getCustomInPlaceResId() == 0) {
8315            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8316                    "with valid animation");
8317        }
8318        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8319        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8320                opts.getCustomInPlaceResId());
8321        mWindowManager.executeAppTransition();
8322    }
8323
8324    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8325        mRecentTasks.remove(tr);
8326        tr.removedFromRecents();
8327        ComponentName component = tr.getBaseIntent().getComponent();
8328        if (component == null) {
8329            Slog.w(TAG, "No component for base intent of task: " + tr);
8330            return;
8331        }
8332
8333        if (!killProcess) {
8334            return;
8335        }
8336
8337        // Determine if the process(es) for this task should be killed.
8338        final String pkg = component.getPackageName();
8339        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8340        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8341        for (int i = 0; i < pmap.size(); i++) {
8342
8343            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8344            for (int j = 0; j < uids.size(); j++) {
8345                ProcessRecord proc = uids.valueAt(j);
8346                if (proc.userId != tr.userId) {
8347                    // Don't kill process for a different user.
8348                    continue;
8349                }
8350                if (proc == mHomeProcess) {
8351                    // Don't kill the home process along with tasks from the same package.
8352                    continue;
8353                }
8354                if (!proc.pkgList.containsKey(pkg)) {
8355                    // Don't kill process that is not associated with this task.
8356                    continue;
8357                }
8358
8359                for (int k = 0; k < proc.activities.size(); k++) {
8360                    TaskRecord otherTask = proc.activities.get(k).task;
8361                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8362                        // Don't kill process(es) that has an activity in a different task that is
8363                        // also in recents.
8364                        return;
8365                    }
8366                }
8367
8368                // Add process to kill list.
8369                procsToKill.add(proc);
8370            }
8371        }
8372
8373        // Find any running services associated with this app and stop if needed.
8374        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8375
8376        // Kill the running processes.
8377        for (int i = 0; i < procsToKill.size(); i++) {
8378            ProcessRecord pr = procsToKill.get(i);
8379            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8380                pr.kill("remove task", true);
8381            } else {
8382                pr.waitingToKill = "remove task";
8383            }
8384        }
8385    }
8386
8387    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8388        // Remove all tasks with activities in the specified package from the list of recent tasks
8389        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8390            TaskRecord tr = mRecentTasks.get(i);
8391            if (tr.userId != userId) continue;
8392
8393            ComponentName cn = tr.intent.getComponent();
8394            if (cn != null && cn.getPackageName().equals(packageName)) {
8395                // If the package name matches, remove the task.
8396                removeTaskByIdLocked(tr.taskId, true);
8397            }
8398        }
8399    }
8400
8401    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8402        final IPackageManager pm = AppGlobals.getPackageManager();
8403        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8404
8405        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8406            TaskRecord tr = mRecentTasks.get(i);
8407            if (tr.userId != userId) continue;
8408
8409            ComponentName cn = tr.intent.getComponent();
8410            if (cn != null && cn.getPackageName().equals(packageName)) {
8411                // Skip if component still exists in the package.
8412                if (componentsKnownToExist.contains(cn)) continue;
8413
8414                try {
8415                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8416                    if (info != null) {
8417                        componentsKnownToExist.add(cn);
8418                    } else {
8419                        removeTaskByIdLocked(tr.taskId, false);
8420                    }
8421                } catch (RemoteException e) {
8422                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8423                }
8424            }
8425        }
8426    }
8427
8428    /**
8429     * Removes the task with the specified task id.
8430     *
8431     * @param taskId Identifier of the task to be removed.
8432     * @param killProcess Kill any process associated with the task if possible.
8433     * @return Returns true if the given task was found and removed.
8434     */
8435    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8436        TaskRecord tr = taskForIdLocked(taskId);
8437        if (tr != null) {
8438            tr.removeTaskActivitiesLocked();
8439            cleanUpRemovedTaskLocked(tr, killProcess);
8440            if (tr.isPersistable) {
8441                notifyTaskPersisterLocked(null, true);
8442            }
8443            return true;
8444        }
8445        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8446        return false;
8447    }
8448
8449    @Override
8450    public boolean removeTask(int taskId) {
8451        synchronized (this) {
8452            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8453                    "removeTask()");
8454            long ident = Binder.clearCallingIdentity();
8455            try {
8456                return removeTaskByIdLocked(taskId, true);
8457            } finally {
8458                Binder.restoreCallingIdentity(ident);
8459            }
8460        }
8461    }
8462
8463    /**
8464     * TODO: Add mController hook
8465     */
8466    @Override
8467    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8468        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8469                "moveTaskToFront()");
8470
8471        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8472        synchronized(this) {
8473            moveTaskToFrontLocked(taskId, flags, options);
8474        }
8475    }
8476
8477    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8478        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8479                Binder.getCallingUid(), -1, -1, "Task to front")) {
8480            ActivityOptions.abort(options);
8481            return;
8482        }
8483        final long origId = Binder.clearCallingIdentity();
8484        try {
8485            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8486            if (task == null) {
8487                Slog.d(TAG, "Could not find task for id: "+ taskId);
8488                return;
8489            }
8490            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8491                mStackSupervisor.showLockTaskToast();
8492                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8493                return;
8494            }
8495            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8496            if (prev != null && prev.isRecentsActivity()) {
8497                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8498            }
8499            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8500        } finally {
8501            Binder.restoreCallingIdentity(origId);
8502        }
8503        ActivityOptions.abort(options);
8504    }
8505
8506    @Override
8507    public void moveTaskToBack(int taskId) {
8508        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8509                "moveTaskToBack()");
8510
8511        synchronized(this) {
8512            TaskRecord tr = taskForIdLocked(taskId);
8513            if (tr != null) {
8514                if (tr == mStackSupervisor.mLockTaskModeTask) {
8515                    mStackSupervisor.showLockTaskToast();
8516                    return;
8517                }
8518                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8519                ActivityStack stack = tr.stack;
8520                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8521                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8522                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8523                        return;
8524                    }
8525                }
8526                final long origId = Binder.clearCallingIdentity();
8527                try {
8528                    stack.moveTaskToBackLocked(taskId, null);
8529                } finally {
8530                    Binder.restoreCallingIdentity(origId);
8531                }
8532            }
8533        }
8534    }
8535
8536    /**
8537     * Moves an activity, and all of the other activities within the same task, to the bottom
8538     * of the history stack.  The activity's order within the task is unchanged.
8539     *
8540     * @param token A reference to the activity we wish to move
8541     * @param nonRoot If false then this only works if the activity is the root
8542     *                of a task; if true it will work for any activity in a task.
8543     * @return Returns true if the move completed, false if not.
8544     */
8545    @Override
8546    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8547        enforceNotIsolatedCaller("moveActivityTaskToBack");
8548        synchronized(this) {
8549            final long origId = Binder.clearCallingIdentity();
8550            try {
8551                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8552                if (taskId >= 0) {
8553                    if ((mStackSupervisor.mLockTaskModeTask != null)
8554                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8555                        mStackSupervisor.showLockTaskToast();
8556                        return false;
8557                    }
8558                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8559                }
8560            } finally {
8561                Binder.restoreCallingIdentity(origId);
8562            }
8563        }
8564        return false;
8565    }
8566
8567    @Override
8568    public void moveTaskBackwards(int task) {
8569        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8570                "moveTaskBackwards()");
8571
8572        synchronized(this) {
8573            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8574                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8575                return;
8576            }
8577            final long origId = Binder.clearCallingIdentity();
8578            moveTaskBackwardsLocked(task);
8579            Binder.restoreCallingIdentity(origId);
8580        }
8581    }
8582
8583    private final void moveTaskBackwardsLocked(int task) {
8584        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8585    }
8586
8587    @Override
8588    public IBinder getHomeActivityToken() throws RemoteException {
8589        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8590                "getHomeActivityToken()");
8591        synchronized (this) {
8592            return mStackSupervisor.getHomeActivityToken();
8593        }
8594    }
8595
8596    @Override
8597    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8598            IActivityContainerCallback callback) throws RemoteException {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "createActivityContainer()");
8601        synchronized (this) {
8602            if (parentActivityToken == null) {
8603                throw new IllegalArgumentException("parent token must not be null");
8604            }
8605            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8606            if (r == null) {
8607                return null;
8608            }
8609            if (callback == null) {
8610                throw new IllegalArgumentException("callback must not be null");
8611            }
8612            return mStackSupervisor.createActivityContainer(r, callback);
8613        }
8614    }
8615
8616    @Override
8617    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8618        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8619                "deleteActivityContainer()");
8620        synchronized (this) {
8621            mStackSupervisor.deleteActivityContainer(container);
8622        }
8623    }
8624
8625    @Override
8626    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8627            throws RemoteException {
8628        synchronized (this) {
8629            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8630            if (stack != null) {
8631                return stack.mActivityContainer;
8632            }
8633            return null;
8634        }
8635    }
8636
8637    @Override
8638    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "moveTaskToStack()");
8641        if (stackId == HOME_STACK_ID) {
8642            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8643                    new RuntimeException("here").fillInStackTrace());
8644        }
8645        synchronized (this) {
8646            long ident = Binder.clearCallingIdentity();
8647            try {
8648                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8649                        + stackId + " toTop=" + toTop);
8650                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8651            } finally {
8652                Binder.restoreCallingIdentity(ident);
8653            }
8654        }
8655    }
8656
8657    @Override
8658    public void resizeStack(int stackBoxId, Rect bounds) {
8659        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8660                "resizeStackBox()");
8661        long ident = Binder.clearCallingIdentity();
8662        try {
8663            mWindowManager.resizeStack(stackBoxId, bounds);
8664        } finally {
8665            Binder.restoreCallingIdentity(ident);
8666        }
8667    }
8668
8669    @Override
8670    public List<StackInfo> getAllStackInfos() {
8671        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8672                "getAllStackInfos()");
8673        long ident = Binder.clearCallingIdentity();
8674        try {
8675            synchronized (this) {
8676                return mStackSupervisor.getAllStackInfosLocked();
8677            }
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681    }
8682
8683    @Override
8684    public StackInfo getStackInfo(int stackId) {
8685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8686                "getStackInfo()");
8687        long ident = Binder.clearCallingIdentity();
8688        try {
8689            synchronized (this) {
8690                return mStackSupervisor.getStackInfoLocked(stackId);
8691            }
8692        } finally {
8693            Binder.restoreCallingIdentity(ident);
8694        }
8695    }
8696
8697    @Override
8698    public boolean isInHomeStack(int taskId) {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "getStackInfo()");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            synchronized (this) {
8704                TaskRecord tr = taskForIdLocked(taskId);
8705                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8706            }
8707        } finally {
8708            Binder.restoreCallingIdentity(ident);
8709        }
8710    }
8711
8712    @Override
8713    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8714        synchronized(this) {
8715            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8716        }
8717    }
8718
8719    private boolean isLockTaskAuthorized(String pkg) {
8720        final DevicePolicyManager dpm = (DevicePolicyManager)
8721                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8722        try {
8723            int uid = mContext.getPackageManager().getPackageUid(pkg,
8724                    Binder.getCallingUserHandle().getIdentifier());
8725            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8726        } catch (NameNotFoundException e) {
8727            return false;
8728        }
8729    }
8730
8731    void startLockTaskMode(TaskRecord task) {
8732        final String pkg;
8733        synchronized (this) {
8734            pkg = task.intent.getComponent().getPackageName();
8735        }
8736        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8737        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8738            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8739                    StatusBarManagerInternal.class);
8740            if (statusBarManager != null) {
8741                statusBarManager.showScreenPinningRequest();
8742            }
8743            return;
8744        }
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            synchronized (this) {
8748                // Since we lost lock on task, make sure it is still there.
8749                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8750                if (task != null) {
8751                    if (!isSystemInitiated
8752                            && ((mStackSupervisor.getFocusedStack() == null)
8753                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8754                        throw new IllegalArgumentException("Invalid task, not in foreground");
8755                    }
8756                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8757                }
8758            }
8759        } finally {
8760            Binder.restoreCallingIdentity(ident);
8761        }
8762    }
8763
8764    @Override
8765    public void startLockTaskMode(int taskId) {
8766        final TaskRecord task;
8767        long ident = Binder.clearCallingIdentity();
8768        try {
8769            synchronized (this) {
8770                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8771            }
8772        } finally {
8773            Binder.restoreCallingIdentity(ident);
8774        }
8775        if (task != null) {
8776            startLockTaskMode(task);
8777        }
8778    }
8779
8780    @Override
8781    public void startLockTaskMode(IBinder token) {
8782        final TaskRecord task;
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            synchronized (this) {
8786                final ActivityRecord r = ActivityRecord.forToken(token);
8787                if (r == null) {
8788                    return;
8789                }
8790                task = r.task;
8791            }
8792        } finally {
8793            Binder.restoreCallingIdentity(ident);
8794        }
8795        if (task != null) {
8796            startLockTaskMode(task);
8797        }
8798    }
8799
8800    @Override
8801    public void startLockTaskModeOnCurrent() throws RemoteException {
8802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8803                "startLockTaskModeOnCurrent");
8804        long ident = Binder.clearCallingIdentity();
8805        try {
8806            ActivityRecord r = null;
8807            synchronized (this) {
8808                r = mStackSupervisor.topRunningActivityLocked();
8809            }
8810            startLockTaskMode(r.task);
8811        } finally {
8812            Binder.restoreCallingIdentity(ident);
8813        }
8814    }
8815
8816    @Override
8817    public void stopLockTaskMode() {
8818        // Verify that the user matches the package of the intent for the TaskRecord
8819        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8820        // and stopLockTaskMode.
8821        final int callingUid = Binder.getCallingUid();
8822        if (callingUid != Process.SYSTEM_UID) {
8823            try {
8824                String pkg =
8825                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8826                int uid = mContext.getPackageManager().getPackageUid(pkg,
8827                        Binder.getCallingUserHandle().getIdentifier());
8828                if (uid != callingUid) {
8829                    throw new SecurityException("Invalid uid, expected " + uid);
8830                }
8831            } catch (NameNotFoundException e) {
8832                Log.d(TAG, "stopLockTaskMode " + e);
8833                return;
8834            }
8835        }
8836        long ident = Binder.clearCallingIdentity();
8837        try {
8838            Log.d(TAG, "stopLockTaskMode");
8839            // Stop lock task
8840            synchronized (this) {
8841                mStackSupervisor.setLockTaskModeLocked(null, false);
8842            }
8843        } finally {
8844            Binder.restoreCallingIdentity(ident);
8845        }
8846    }
8847
8848    @Override
8849    public void stopLockTaskModeOnCurrent() throws RemoteException {
8850        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8851                "stopLockTaskModeOnCurrent");
8852        long ident = Binder.clearCallingIdentity();
8853        try {
8854            stopLockTaskMode();
8855        } finally {
8856            Binder.restoreCallingIdentity(ident);
8857        }
8858    }
8859
8860    @Override
8861    public boolean isInLockTaskMode() {
8862        synchronized (this) {
8863            return mStackSupervisor.isInLockTaskMode();
8864        }
8865    }
8866
8867    // =========================================================
8868    // CONTENT PROVIDERS
8869    // =========================================================
8870
8871    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8872        List<ProviderInfo> providers = null;
8873        try {
8874            providers = AppGlobals.getPackageManager().
8875                queryContentProviders(app.processName, app.uid,
8876                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8877        } catch (RemoteException ex) {
8878        }
8879        if (DEBUG_MU)
8880            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8881        int userId = app.userId;
8882        if (providers != null) {
8883            int N = providers.size();
8884            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8885            for (int i=0; i<N; i++) {
8886                ProviderInfo cpi =
8887                    (ProviderInfo)providers.get(i);
8888                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8889                        cpi.name, cpi.flags);
8890                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8891                    // This is a singleton provider, but a user besides the
8892                    // default user is asking to initialize a process it runs
8893                    // in...  well, no, it doesn't actually run in this process,
8894                    // it runs in the process of the default user.  Get rid of it.
8895                    providers.remove(i);
8896                    N--;
8897                    i--;
8898                    continue;
8899                }
8900
8901                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8902                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8903                if (cpr == null) {
8904                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8905                    mProviderMap.putProviderByClass(comp, cpr);
8906                }
8907                if (DEBUG_MU)
8908                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8909                app.pubProviders.put(cpi.name, cpr);
8910                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8911                    // Don't add this if it is a platform component that is marked
8912                    // to run in multiple processes, because this is actually
8913                    // part of the framework so doesn't make sense to track as a
8914                    // separate apk in the process.
8915                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8916                            mProcessStats);
8917                }
8918                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8919            }
8920        }
8921        return providers;
8922    }
8923
8924    /**
8925     * Check if {@link ProcessRecord} has a possible chance at accessing the
8926     * given {@link ProviderInfo}. Final permission checking is always done
8927     * in {@link ContentProvider}.
8928     */
8929    private final String checkContentProviderPermissionLocked(
8930            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8931        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8932        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8933        boolean checkedGrants = false;
8934        if (checkUser) {
8935            // Looking for cross-user grants before enforcing the typical cross-users permissions
8936            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8937            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8938                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8939                    return null;
8940                }
8941                checkedGrants = true;
8942            }
8943            userId = handleIncomingUser(callingPid, callingUid, userId,
8944                    false, ALLOW_NON_FULL,
8945                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8946            if (userId != tmpTargetUserId) {
8947                // When we actually went to determine the final targer user ID, this ended
8948                // up different than our initial check for the authority.  This is because
8949                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8950                // SELF.  So we need to re-check the grants again.
8951                checkedGrants = false;
8952            }
8953        }
8954        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8955                cpi.applicationInfo.uid, cpi.exported)
8956                == PackageManager.PERMISSION_GRANTED) {
8957            return null;
8958        }
8959        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8960                cpi.applicationInfo.uid, cpi.exported)
8961                == PackageManager.PERMISSION_GRANTED) {
8962            return null;
8963        }
8964
8965        PathPermission[] pps = cpi.pathPermissions;
8966        if (pps != null) {
8967            int i = pps.length;
8968            while (i > 0) {
8969                i--;
8970                PathPermission pp = pps[i];
8971                String pprperm = pp.getReadPermission();
8972                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8973                        cpi.applicationInfo.uid, cpi.exported)
8974                        == PackageManager.PERMISSION_GRANTED) {
8975                    return null;
8976                }
8977                String ppwperm = pp.getWritePermission();
8978                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8979                        cpi.applicationInfo.uid, cpi.exported)
8980                        == PackageManager.PERMISSION_GRANTED) {
8981                    return null;
8982                }
8983            }
8984        }
8985        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8986            return null;
8987        }
8988
8989        String msg;
8990        if (!cpi.exported) {
8991            msg = "Permission Denial: opening provider " + cpi.name
8992                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8993                    + ", uid=" + callingUid + ") that is not exported from uid "
8994                    + cpi.applicationInfo.uid;
8995        } else {
8996            msg = "Permission Denial: opening provider " + cpi.name
8997                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8998                    + ", uid=" + callingUid + ") requires "
8999                    + cpi.readPermission + " or " + cpi.writePermission;
9000        }
9001        Slog.w(TAG, msg);
9002        return msg;
9003    }
9004
9005    /**
9006     * Returns if the ContentProvider has granted a uri to callingUid
9007     */
9008    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9009        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9010        if (perms != null) {
9011            for (int i=perms.size()-1; i>=0; i--) {
9012                GrantUri grantUri = perms.keyAt(i);
9013                if (grantUri.sourceUserId == userId || !checkUser) {
9014                    if (matchesProvider(grantUri.uri, cpi)) {
9015                        return true;
9016                    }
9017                }
9018            }
9019        }
9020        return false;
9021    }
9022
9023    /**
9024     * Returns true if the uri authority is one of the authorities specified in the provider.
9025     */
9026    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9027        String uriAuth = uri.getAuthority();
9028        String cpiAuth = cpi.authority;
9029        if (cpiAuth.indexOf(';') == -1) {
9030            return cpiAuth.equals(uriAuth);
9031        }
9032        String[] cpiAuths = cpiAuth.split(";");
9033        int length = cpiAuths.length;
9034        for (int i = 0; i < length; i++) {
9035            if (cpiAuths[i].equals(uriAuth)) return true;
9036        }
9037        return false;
9038    }
9039
9040    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9041            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9042        if (r != null) {
9043            for (int i=0; i<r.conProviders.size(); i++) {
9044                ContentProviderConnection conn = r.conProviders.get(i);
9045                if (conn.provider == cpr) {
9046                    if (DEBUG_PROVIDER) Slog.v(TAG,
9047                            "Adding provider requested by "
9048                            + r.processName + " from process "
9049                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9050                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9051                    if (stable) {
9052                        conn.stableCount++;
9053                        conn.numStableIncs++;
9054                    } else {
9055                        conn.unstableCount++;
9056                        conn.numUnstableIncs++;
9057                    }
9058                    return conn;
9059                }
9060            }
9061            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9062            if (stable) {
9063                conn.stableCount = 1;
9064                conn.numStableIncs = 1;
9065            } else {
9066                conn.unstableCount = 1;
9067                conn.numUnstableIncs = 1;
9068            }
9069            cpr.connections.add(conn);
9070            r.conProviders.add(conn);
9071            return conn;
9072        }
9073        cpr.addExternalProcessHandleLocked(externalProcessToken);
9074        return null;
9075    }
9076
9077    boolean decProviderCountLocked(ContentProviderConnection conn,
9078            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9079        if (conn != null) {
9080            cpr = conn.provider;
9081            if (DEBUG_PROVIDER) Slog.v(TAG,
9082                    "Removing provider requested by "
9083                    + conn.client.processName + " from process "
9084                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9085                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9086            if (stable) {
9087                conn.stableCount--;
9088            } else {
9089                conn.unstableCount--;
9090            }
9091            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9092                cpr.connections.remove(conn);
9093                conn.client.conProviders.remove(conn);
9094                return true;
9095            }
9096            return false;
9097        }
9098        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9099        return false;
9100    }
9101
9102    private void checkTime(long startTime, String where) {
9103        long now = SystemClock.elapsedRealtime();
9104        if ((now-startTime) > 1000) {
9105            // If we are taking more than a second, log about it.
9106            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9107        }
9108    }
9109
9110    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9111            String name, IBinder token, boolean stable, int userId) {
9112        ContentProviderRecord cpr;
9113        ContentProviderConnection conn = null;
9114        ProviderInfo cpi = null;
9115
9116        synchronized(this) {
9117            long startTime = SystemClock.elapsedRealtime();
9118
9119            ProcessRecord r = null;
9120            if (caller != null) {
9121                r = getRecordForAppLocked(caller);
9122                if (r == null) {
9123                    throw new SecurityException(
9124                            "Unable to find app for caller " + caller
9125                          + " (pid=" + Binder.getCallingPid()
9126                          + ") when getting content provider " + name);
9127                }
9128            }
9129
9130            boolean checkCrossUser = true;
9131
9132            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9133
9134            // First check if this content provider has been published...
9135            cpr = mProviderMap.getProviderByName(name, userId);
9136            // If that didn't work, check if it exists for user 0 and then
9137            // verify that it's a singleton provider before using it.
9138            if (cpr == null && userId != UserHandle.USER_OWNER) {
9139                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9140                if (cpr != null) {
9141                    cpi = cpr.info;
9142                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9143                            cpi.name, cpi.flags)
9144                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9145                        userId = UserHandle.USER_OWNER;
9146                        checkCrossUser = false;
9147                    } else {
9148                        cpr = null;
9149                        cpi = null;
9150                    }
9151                }
9152            }
9153
9154            boolean providerRunning = cpr != null;
9155            if (providerRunning) {
9156                cpi = cpr.info;
9157                String msg;
9158                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9159                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9160                        != null) {
9161                    throw new SecurityException(msg);
9162                }
9163                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9164
9165                if (r != null && cpr.canRunHere(r)) {
9166                    // This provider has been published or is in the process
9167                    // of being published...  but it is also allowed to run
9168                    // in the caller's process, so don't make a connection
9169                    // and just let the caller instantiate its own instance.
9170                    ContentProviderHolder holder = cpr.newHolder(null);
9171                    // don't give caller the provider object, it needs
9172                    // to make its own.
9173                    holder.provider = null;
9174                    return holder;
9175                }
9176
9177                final long origId = Binder.clearCallingIdentity();
9178
9179                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9180
9181                // In this case the provider instance already exists, so we can
9182                // return it right away.
9183                conn = incProviderCountLocked(r, cpr, token, stable);
9184                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9185                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9186                        // If this is a perceptible app accessing the provider,
9187                        // make sure to count it as being accessed and thus
9188                        // back up on the LRU list.  This is good because
9189                        // content providers are often expensive to start.
9190                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9191                        updateLruProcessLocked(cpr.proc, false, null);
9192                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9193                    }
9194                }
9195
9196                if (cpr.proc != null) {
9197                    if (false) {
9198                        if (cpr.name.flattenToShortString().equals(
9199                                "com.android.providers.calendar/.CalendarProvider2")) {
9200                            Slog.v(TAG, "****************** KILLING "
9201                                + cpr.name.flattenToShortString());
9202                            Process.killProcess(cpr.proc.pid);
9203                        }
9204                    }
9205                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9206                    boolean success = updateOomAdjLocked(cpr.proc);
9207                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9208                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9209                    // NOTE: there is still a race here where a signal could be
9210                    // pending on the process even though we managed to update its
9211                    // adj level.  Not sure what to do about this, but at least
9212                    // the race is now smaller.
9213                    if (!success) {
9214                        // Uh oh...  it looks like the provider's process
9215                        // has been killed on us.  We need to wait for a new
9216                        // process to be started, and make sure its death
9217                        // doesn't kill our process.
9218                        Slog.i(TAG,
9219                                "Existing provider " + cpr.name.flattenToShortString()
9220                                + " is crashing; detaching " + r);
9221                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9222                        checkTime(startTime, "getContentProviderImpl: before appDied");
9223                        appDiedLocked(cpr.proc);
9224                        checkTime(startTime, "getContentProviderImpl: after appDied");
9225                        if (!lastRef) {
9226                            // This wasn't the last ref our process had on
9227                            // the provider...  we have now been killed, bail.
9228                            return null;
9229                        }
9230                        providerRunning = false;
9231                        conn = null;
9232                    }
9233                }
9234
9235                Binder.restoreCallingIdentity(origId);
9236            }
9237
9238            boolean singleton;
9239            if (!providerRunning) {
9240                try {
9241                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9242                    cpi = AppGlobals.getPackageManager().
9243                        resolveContentProvider(name,
9244                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9245                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9246                } catch (RemoteException ex) {
9247                }
9248                if (cpi == null) {
9249                    return null;
9250                }
9251                // If the provider is a singleton AND
9252                // (it's a call within the same user || the provider is a
9253                // privileged app)
9254                // Then allow connecting to the singleton provider
9255                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9256                        cpi.name, cpi.flags)
9257                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9258                if (singleton) {
9259                    userId = UserHandle.USER_OWNER;
9260                }
9261                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9262                checkTime(startTime, "getContentProviderImpl: got app info for user");
9263
9264                String msg;
9265                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9266                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9267                        != null) {
9268                    throw new SecurityException(msg);
9269                }
9270                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9271
9272                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9273                        && !cpi.processName.equals("system")) {
9274                    // If this content provider does not run in the system
9275                    // process, and the system is not yet ready to run other
9276                    // processes, then fail fast instead of hanging.
9277                    throw new IllegalArgumentException(
9278                            "Attempt to launch content provider before system ready");
9279                }
9280
9281                // Make sure that the user who owns this provider is started.  If not,
9282                // we don't want to allow it to run.
9283                if (mStartedUsers.get(userId) == null) {
9284                    Slog.w(TAG, "Unable to launch app "
9285                            + cpi.applicationInfo.packageName + "/"
9286                            + cpi.applicationInfo.uid + " for provider "
9287                            + name + ": user " + userId + " is stopped");
9288                    return null;
9289                }
9290
9291                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9292                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9293                cpr = mProviderMap.getProviderByClass(comp, userId);
9294                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9295                final boolean firstClass = cpr == null;
9296                if (firstClass) {
9297                    final long ident = Binder.clearCallingIdentity();
9298                    try {
9299                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9300                        ApplicationInfo ai =
9301                            AppGlobals.getPackageManager().
9302                                getApplicationInfo(
9303                                        cpi.applicationInfo.packageName,
9304                                        STOCK_PM_FLAGS, userId);
9305                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9306                        if (ai == null) {
9307                            Slog.w(TAG, "No package info for content provider "
9308                                    + cpi.name);
9309                            return null;
9310                        }
9311                        ai = getAppInfoForUser(ai, userId);
9312                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9313                    } catch (RemoteException ex) {
9314                        // pm is in same process, this will never happen.
9315                    } finally {
9316                        Binder.restoreCallingIdentity(ident);
9317                    }
9318                }
9319
9320                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9321
9322                if (r != null && cpr.canRunHere(r)) {
9323                    // If this is a multiprocess provider, then just return its
9324                    // info and allow the caller to instantiate it.  Only do
9325                    // this if the provider is the same user as the caller's
9326                    // process, or can run as root (so can be in any process).
9327                    return cpr.newHolder(null);
9328                }
9329
9330                if (DEBUG_PROVIDER) {
9331                    RuntimeException e = new RuntimeException("here");
9332                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9333                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9334                }
9335
9336                // This is single process, and our app is now connecting to it.
9337                // See if we are already in the process of launching this
9338                // provider.
9339                final int N = mLaunchingProviders.size();
9340                int i;
9341                for (i=0; i<N; i++) {
9342                    if (mLaunchingProviders.get(i) == cpr) {
9343                        break;
9344                    }
9345                }
9346
9347                // If the provider is not already being launched, then get it
9348                // started.
9349                if (i >= N) {
9350                    final long origId = Binder.clearCallingIdentity();
9351
9352                    try {
9353                        // Content provider is now in use, its package can't be stopped.
9354                        try {
9355                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9356                            AppGlobals.getPackageManager().setPackageStoppedState(
9357                                    cpr.appInfo.packageName, false, userId);
9358                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9359                        } catch (RemoteException e) {
9360                        } catch (IllegalArgumentException e) {
9361                            Slog.w(TAG, "Failed trying to unstop package "
9362                                    + cpr.appInfo.packageName + ": " + e);
9363                        }
9364
9365                        // Use existing process if already started
9366                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9367                        ProcessRecord proc = getProcessRecordLocked(
9368                                cpi.processName, cpr.appInfo.uid, false);
9369                        if (proc != null && proc.thread != null) {
9370                            if (DEBUG_PROVIDER) {
9371                                Slog.d(TAG, "Installing in existing process " + proc);
9372                            }
9373                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9374                            proc.pubProviders.put(cpi.name, cpr);
9375                            try {
9376                                proc.thread.scheduleInstallProvider(cpi);
9377                            } catch (RemoteException e) {
9378                            }
9379                        } else {
9380                            checkTime(startTime, "getContentProviderImpl: before start process");
9381                            proc = startProcessLocked(cpi.processName,
9382                                    cpr.appInfo, false, 0, "content provider",
9383                                    new ComponentName(cpi.applicationInfo.packageName,
9384                                            cpi.name), false, false, false);
9385                            checkTime(startTime, "getContentProviderImpl: after start process");
9386                            if (proc == null) {
9387                                Slog.w(TAG, "Unable to launch app "
9388                                        + cpi.applicationInfo.packageName + "/"
9389                                        + cpi.applicationInfo.uid + " for provider "
9390                                        + name + ": process is bad");
9391                                return null;
9392                            }
9393                        }
9394                        cpr.launchingApp = proc;
9395                        mLaunchingProviders.add(cpr);
9396                    } finally {
9397                        Binder.restoreCallingIdentity(origId);
9398                    }
9399                }
9400
9401                checkTime(startTime, "getContentProviderImpl: updating data structures");
9402
9403                // Make sure the provider is published (the same provider class
9404                // may be published under multiple names).
9405                if (firstClass) {
9406                    mProviderMap.putProviderByClass(comp, cpr);
9407                }
9408
9409                mProviderMap.putProviderByName(name, cpr);
9410                conn = incProviderCountLocked(r, cpr, token, stable);
9411                if (conn != null) {
9412                    conn.waiting = true;
9413                }
9414            }
9415            checkTime(startTime, "getContentProviderImpl: done!");
9416        }
9417
9418        // Wait for the provider to be published...
9419        synchronized (cpr) {
9420            while (cpr.provider == null) {
9421                if (cpr.launchingApp == null) {
9422                    Slog.w(TAG, "Unable to launch app "
9423                            + cpi.applicationInfo.packageName + "/"
9424                            + cpi.applicationInfo.uid + " for provider "
9425                            + name + ": launching app became null");
9426                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9427                            UserHandle.getUserId(cpi.applicationInfo.uid),
9428                            cpi.applicationInfo.packageName,
9429                            cpi.applicationInfo.uid, name);
9430                    return null;
9431                }
9432                try {
9433                    if (DEBUG_MU) {
9434                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9435                                + cpr.launchingApp);
9436                    }
9437                    if (conn != null) {
9438                        conn.waiting = true;
9439                    }
9440                    cpr.wait();
9441                } catch (InterruptedException ex) {
9442                } finally {
9443                    if (conn != null) {
9444                        conn.waiting = false;
9445                    }
9446                }
9447            }
9448        }
9449        return cpr != null ? cpr.newHolder(conn) : null;
9450    }
9451
9452    @Override
9453    public final ContentProviderHolder getContentProvider(
9454            IApplicationThread caller, String name, int userId, boolean stable) {
9455        enforceNotIsolatedCaller("getContentProvider");
9456        if (caller == null) {
9457            String msg = "null IApplicationThread when getting content provider "
9458                    + name;
9459            Slog.w(TAG, msg);
9460            throw new SecurityException(msg);
9461        }
9462        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9463        // with cross-user grant.
9464        return getContentProviderImpl(caller, name, null, stable, userId);
9465    }
9466
9467    public ContentProviderHolder getContentProviderExternal(
9468            String name, int userId, IBinder token) {
9469        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9470            "Do not have permission in call getContentProviderExternal()");
9471        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9472                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9473        return getContentProviderExternalUnchecked(name, token, userId);
9474    }
9475
9476    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9477            IBinder token, int userId) {
9478        return getContentProviderImpl(null, name, token, true, userId);
9479    }
9480
9481    /**
9482     * Drop a content provider from a ProcessRecord's bookkeeping
9483     */
9484    public void removeContentProvider(IBinder connection, boolean stable) {
9485        enforceNotIsolatedCaller("removeContentProvider");
9486        long ident = Binder.clearCallingIdentity();
9487        try {
9488            synchronized (this) {
9489                ContentProviderConnection conn;
9490                try {
9491                    conn = (ContentProviderConnection)connection;
9492                } catch (ClassCastException e) {
9493                    String msg ="removeContentProvider: " + connection
9494                            + " not a ContentProviderConnection";
9495                    Slog.w(TAG, msg);
9496                    throw new IllegalArgumentException(msg);
9497                }
9498                if (conn == null) {
9499                    throw new NullPointerException("connection is null");
9500                }
9501                if (decProviderCountLocked(conn, null, null, stable)) {
9502                    updateOomAdjLocked();
9503                }
9504            }
9505        } finally {
9506            Binder.restoreCallingIdentity(ident);
9507        }
9508    }
9509
9510    public void removeContentProviderExternal(String name, IBinder token) {
9511        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9512            "Do not have permission in call removeContentProviderExternal()");
9513        int userId = UserHandle.getCallingUserId();
9514        long ident = Binder.clearCallingIdentity();
9515        try {
9516            removeContentProviderExternalUnchecked(name, token, userId);
9517        } finally {
9518            Binder.restoreCallingIdentity(ident);
9519        }
9520    }
9521
9522    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9523        synchronized (this) {
9524            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9525            if(cpr == null) {
9526                //remove from mProvidersByClass
9527                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9528                return;
9529            }
9530
9531            //update content provider record entry info
9532            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9533            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9534            if (localCpr.hasExternalProcessHandles()) {
9535                if (localCpr.removeExternalProcessHandleLocked(token)) {
9536                    updateOomAdjLocked();
9537                } else {
9538                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9539                            + " with no external reference for token: "
9540                            + token + ".");
9541                }
9542            } else {
9543                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9544                        + " with no external references.");
9545            }
9546        }
9547    }
9548
9549    public final void publishContentProviders(IApplicationThread caller,
9550            List<ContentProviderHolder> providers) {
9551        if (providers == null) {
9552            return;
9553        }
9554
9555        enforceNotIsolatedCaller("publishContentProviders");
9556        synchronized (this) {
9557            final ProcessRecord r = getRecordForAppLocked(caller);
9558            if (DEBUG_MU)
9559                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9560            if (r == null) {
9561                throw new SecurityException(
9562                        "Unable to find app for caller " + caller
9563                      + " (pid=" + Binder.getCallingPid()
9564                      + ") when publishing content providers");
9565            }
9566
9567            final long origId = Binder.clearCallingIdentity();
9568
9569            final int N = providers.size();
9570            for (int i=0; i<N; i++) {
9571                ContentProviderHolder src = providers.get(i);
9572                if (src == null || src.info == null || src.provider == null) {
9573                    continue;
9574                }
9575                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9576                if (DEBUG_MU)
9577                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9578                if (dst != null) {
9579                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9580                    mProviderMap.putProviderByClass(comp, dst);
9581                    String names[] = dst.info.authority.split(";");
9582                    for (int j = 0; j < names.length; j++) {
9583                        mProviderMap.putProviderByName(names[j], dst);
9584                    }
9585
9586                    int NL = mLaunchingProviders.size();
9587                    int j;
9588                    for (j=0; j<NL; j++) {
9589                        if (mLaunchingProviders.get(j) == dst) {
9590                            mLaunchingProviders.remove(j);
9591                            j--;
9592                            NL--;
9593                        }
9594                    }
9595                    synchronized (dst) {
9596                        dst.provider = src.provider;
9597                        dst.proc = r;
9598                        dst.notifyAll();
9599                    }
9600                    updateOomAdjLocked(r);
9601                }
9602            }
9603
9604            Binder.restoreCallingIdentity(origId);
9605        }
9606    }
9607
9608    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9609        ContentProviderConnection conn;
9610        try {
9611            conn = (ContentProviderConnection)connection;
9612        } catch (ClassCastException e) {
9613            String msg ="refContentProvider: " + connection
9614                    + " not a ContentProviderConnection";
9615            Slog.w(TAG, msg);
9616            throw new IllegalArgumentException(msg);
9617        }
9618        if (conn == null) {
9619            throw new NullPointerException("connection is null");
9620        }
9621
9622        synchronized (this) {
9623            if (stable > 0) {
9624                conn.numStableIncs += stable;
9625            }
9626            stable = conn.stableCount + stable;
9627            if (stable < 0) {
9628                throw new IllegalStateException("stableCount < 0: " + stable);
9629            }
9630
9631            if (unstable > 0) {
9632                conn.numUnstableIncs += unstable;
9633            }
9634            unstable = conn.unstableCount + unstable;
9635            if (unstable < 0) {
9636                throw new IllegalStateException("unstableCount < 0: " + unstable);
9637            }
9638
9639            if ((stable+unstable) <= 0) {
9640                throw new IllegalStateException("ref counts can't go to zero here: stable="
9641                        + stable + " unstable=" + unstable);
9642            }
9643            conn.stableCount = stable;
9644            conn.unstableCount = unstable;
9645            return !conn.dead;
9646        }
9647    }
9648
9649    public void unstableProviderDied(IBinder connection) {
9650        ContentProviderConnection conn;
9651        try {
9652            conn = (ContentProviderConnection)connection;
9653        } catch (ClassCastException e) {
9654            String msg ="refContentProvider: " + connection
9655                    + " not a ContentProviderConnection";
9656            Slog.w(TAG, msg);
9657            throw new IllegalArgumentException(msg);
9658        }
9659        if (conn == null) {
9660            throw new NullPointerException("connection is null");
9661        }
9662
9663        // Safely retrieve the content provider associated with the connection.
9664        IContentProvider provider;
9665        synchronized (this) {
9666            provider = conn.provider.provider;
9667        }
9668
9669        if (provider == null) {
9670            // Um, yeah, we're way ahead of you.
9671            return;
9672        }
9673
9674        // Make sure the caller is being honest with us.
9675        if (provider.asBinder().pingBinder()) {
9676            // Er, no, still looks good to us.
9677            synchronized (this) {
9678                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9679                        + " says " + conn + " died, but we don't agree");
9680                return;
9681            }
9682        }
9683
9684        // Well look at that!  It's dead!
9685        synchronized (this) {
9686            if (conn.provider.provider != provider) {
9687                // But something changed...  good enough.
9688                return;
9689            }
9690
9691            ProcessRecord proc = conn.provider.proc;
9692            if (proc == null || proc.thread == null) {
9693                // Seems like the process is already cleaned up.
9694                return;
9695            }
9696
9697            // As far as we're concerned, this is just like receiving a
9698            // death notification...  just a bit prematurely.
9699            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9700                    + ") early provider death");
9701            final long ident = Binder.clearCallingIdentity();
9702            try {
9703                appDiedLocked(proc);
9704            } finally {
9705                Binder.restoreCallingIdentity(ident);
9706            }
9707        }
9708    }
9709
9710    @Override
9711    public void appNotRespondingViaProvider(IBinder connection) {
9712        enforceCallingPermission(
9713                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9714
9715        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9716        if (conn == null) {
9717            Slog.w(TAG, "ContentProviderConnection is null");
9718            return;
9719        }
9720
9721        final ProcessRecord host = conn.provider.proc;
9722        if (host == null) {
9723            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9724            return;
9725        }
9726
9727        final long token = Binder.clearCallingIdentity();
9728        try {
9729            appNotResponding(host, null, null, false, "ContentProvider not responding");
9730        } finally {
9731            Binder.restoreCallingIdentity(token);
9732        }
9733    }
9734
9735    public final void installSystemProviders() {
9736        List<ProviderInfo> providers;
9737        synchronized (this) {
9738            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9739            providers = generateApplicationProvidersLocked(app);
9740            if (providers != null) {
9741                for (int i=providers.size()-1; i>=0; i--) {
9742                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9743                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9744                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9745                                + ": not system .apk");
9746                        providers.remove(i);
9747                    }
9748                }
9749            }
9750        }
9751        if (providers != null) {
9752            mSystemThread.installSystemProviders(providers);
9753        }
9754
9755        mCoreSettingsObserver = new CoreSettingsObserver(this);
9756
9757        //mUsageStatsService.monitorPackages();
9758    }
9759
9760    /**
9761     * Allows apps to retrieve the MIME type of a URI.
9762     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9763     * users, then it does not need permission to access the ContentProvider.
9764     * Either, it needs cross-user uri grants.
9765     *
9766     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9767     *
9768     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9769     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9770     */
9771    public String getProviderMimeType(Uri uri, int userId) {
9772        enforceNotIsolatedCaller("getProviderMimeType");
9773        final String name = uri.getAuthority();
9774        int callingUid = Binder.getCallingUid();
9775        int callingPid = Binder.getCallingPid();
9776        long ident = 0;
9777        boolean clearedIdentity = false;
9778        userId = unsafeConvertIncomingUser(userId);
9779        if (canClearIdentity(callingPid, callingUid, userId)) {
9780            clearedIdentity = true;
9781            ident = Binder.clearCallingIdentity();
9782        }
9783        ContentProviderHolder holder = null;
9784        try {
9785            holder = getContentProviderExternalUnchecked(name, null, userId);
9786            if (holder != null) {
9787                return holder.provider.getType(uri);
9788            }
9789        } catch (RemoteException e) {
9790            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9791            return null;
9792        } finally {
9793            // We need to clear the identity to call removeContentProviderExternalUnchecked
9794            if (!clearedIdentity) {
9795                ident = Binder.clearCallingIdentity();
9796            }
9797            try {
9798                if (holder != null) {
9799                    removeContentProviderExternalUnchecked(name, null, userId);
9800                }
9801            } finally {
9802                Binder.restoreCallingIdentity(ident);
9803            }
9804        }
9805
9806        return null;
9807    }
9808
9809    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9810        if (UserHandle.getUserId(callingUid) == userId) {
9811            return true;
9812        }
9813        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9814                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9815                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9816                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9817                return true;
9818        }
9819        return false;
9820    }
9821
9822    // =========================================================
9823    // GLOBAL MANAGEMENT
9824    // =========================================================
9825
9826    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9827            boolean isolated, int isolatedUid) {
9828        String proc = customProcess != null ? customProcess : info.processName;
9829        BatteryStatsImpl.Uid.Proc ps = null;
9830        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9831        int uid = info.uid;
9832        if (isolated) {
9833            if (isolatedUid == 0) {
9834                int userId = UserHandle.getUserId(uid);
9835                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9836                while (true) {
9837                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9838                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9839                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9840                    }
9841                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9842                    mNextIsolatedProcessUid++;
9843                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9844                        // No process for this uid, use it.
9845                        break;
9846                    }
9847                    stepsLeft--;
9848                    if (stepsLeft <= 0) {
9849                        return null;
9850                    }
9851                }
9852            } else {
9853                // Special case for startIsolatedProcess (internal only), where
9854                // the uid of the isolated process is specified by the caller.
9855                uid = isolatedUid;
9856            }
9857        }
9858        return new ProcessRecord(stats, info, proc, uid);
9859    }
9860
9861    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9862            String abiOverride) {
9863        ProcessRecord app;
9864        if (!isolated) {
9865            app = getProcessRecordLocked(info.processName, info.uid, true);
9866        } else {
9867            app = null;
9868        }
9869
9870        if (app == null) {
9871            app = newProcessRecordLocked(info, null, isolated, 0);
9872            mProcessNames.put(info.processName, app.uid, app);
9873            if (isolated) {
9874                mIsolatedProcesses.put(app.uid, app);
9875            }
9876            updateLruProcessLocked(app, false, null);
9877            updateOomAdjLocked();
9878        }
9879
9880        // This package really, really can not be stopped.
9881        try {
9882            AppGlobals.getPackageManager().setPackageStoppedState(
9883                    info.packageName, false, UserHandle.getUserId(app.uid));
9884        } catch (RemoteException e) {
9885        } catch (IllegalArgumentException e) {
9886            Slog.w(TAG, "Failed trying to unstop package "
9887                    + info.packageName + ": " + e);
9888        }
9889
9890        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9891                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9892            app.persistent = true;
9893            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9894        }
9895        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9896            mPersistentStartingProcesses.add(app);
9897            startProcessLocked(app, "added application", app.processName, abiOverride,
9898                    null /* entryPoint */, null /* entryPointArgs */);
9899        }
9900
9901        return app;
9902    }
9903
9904    public void unhandledBack() {
9905        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9906                "unhandledBack()");
9907
9908        synchronized(this) {
9909            final long origId = Binder.clearCallingIdentity();
9910            try {
9911                getFocusedStack().unhandledBackLocked();
9912            } finally {
9913                Binder.restoreCallingIdentity(origId);
9914            }
9915        }
9916    }
9917
9918    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9919        enforceNotIsolatedCaller("openContentUri");
9920        final int userId = UserHandle.getCallingUserId();
9921        String name = uri.getAuthority();
9922        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9923        ParcelFileDescriptor pfd = null;
9924        if (cph != null) {
9925            // We record the binder invoker's uid in thread-local storage before
9926            // going to the content provider to open the file.  Later, in the code
9927            // that handles all permissions checks, we look for this uid and use
9928            // that rather than the Activity Manager's own uid.  The effect is that
9929            // we do the check against the caller's permissions even though it looks
9930            // to the content provider like the Activity Manager itself is making
9931            // the request.
9932            Binder token = new Binder();
9933            sCallerIdentity.set(new Identity(
9934                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9935            try {
9936                pfd = cph.provider.openFile(null, uri, "r", null, token);
9937            } catch (FileNotFoundException e) {
9938                // do nothing; pfd will be returned null
9939            } finally {
9940                // Ensure that whatever happens, we clean up the identity state
9941                sCallerIdentity.remove();
9942            }
9943
9944            // We've got the fd now, so we're done with the provider.
9945            removeContentProviderExternalUnchecked(name, null, userId);
9946        } else {
9947            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9948        }
9949        return pfd;
9950    }
9951
9952    // Actually is sleeping or shutting down or whatever else in the future
9953    // is an inactive state.
9954    public boolean isSleepingOrShuttingDown() {
9955        return isSleeping() || mShuttingDown;
9956    }
9957
9958    public boolean isSleeping() {
9959        return mSleeping;
9960    }
9961
9962    void onWakefulnessChanged(int wakefulness) {
9963        synchronized(this) {
9964            mWakefulness = wakefulness;
9965            updateSleepIfNeededLocked();
9966        }
9967    }
9968
9969    void finishRunningVoiceLocked() {
9970        if (mRunningVoice) {
9971            mRunningVoice = false;
9972            updateSleepIfNeededLocked();
9973        }
9974    }
9975
9976    void updateSleepIfNeededLocked() {
9977        if (mSleeping && !shouldSleepLocked()) {
9978            mSleeping = false;
9979            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9980        } else if (!mSleeping && shouldSleepLocked()) {
9981            mSleeping = true;
9982            mStackSupervisor.goingToSleepLocked();
9983
9984            // Initialize the wake times of all processes.
9985            checkExcessivePowerUsageLocked(false);
9986            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9987            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9988            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9989        }
9990    }
9991
9992    private boolean shouldSleepLocked() {
9993        // Resume applications while running a voice interactor.
9994        if (mRunningVoice) {
9995            return false;
9996        }
9997
9998        switch (mWakefulness) {
9999            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10000            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10001                // If we're interactive but applications are already paused then defer
10002                // resuming them until the lock screen is hidden.
10003                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10004            case PowerManagerInternal.WAKEFULNESS_DOZING:
10005                // If we're dozing then pause applications whenever the lock screen is shown.
10006                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10007            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10008            default:
10009                // If we're asleep then pause applications unconditionally.
10010                return true;
10011        }
10012    }
10013
10014    /** Pokes the task persister. */
10015    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10016        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10017            // Never persist the home stack.
10018            return;
10019        }
10020        mTaskPersister.wakeup(task, flush);
10021    }
10022
10023    /** Notifies all listeners when the task stack has changed. */
10024    void notifyTaskStackChangedLocked() {
10025        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10026        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10027        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10028    }
10029
10030    @Override
10031    public boolean shutdown(int timeout) {
10032        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10033                != PackageManager.PERMISSION_GRANTED) {
10034            throw new SecurityException("Requires permission "
10035                    + android.Manifest.permission.SHUTDOWN);
10036        }
10037
10038        boolean timedout = false;
10039
10040        synchronized(this) {
10041            mShuttingDown = true;
10042            updateEventDispatchingLocked();
10043            timedout = mStackSupervisor.shutdownLocked(timeout);
10044        }
10045
10046        mAppOpsService.shutdown();
10047        if (mUsageStatsService != null) {
10048            mUsageStatsService.prepareShutdown();
10049        }
10050        mBatteryStatsService.shutdown();
10051        synchronized (this) {
10052            mProcessStats.shutdownLocked();
10053            notifyTaskPersisterLocked(null, true);
10054        }
10055
10056        return timedout;
10057    }
10058
10059    public final void activitySlept(IBinder token) {
10060        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10061
10062        final long origId = Binder.clearCallingIdentity();
10063
10064        synchronized (this) {
10065            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10066            if (r != null) {
10067                mStackSupervisor.activitySleptLocked(r);
10068            }
10069        }
10070
10071        Binder.restoreCallingIdentity(origId);
10072    }
10073
10074    private String lockScreenShownToString() {
10075        switch (mLockScreenShown) {
10076            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10077            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10078            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10079            default: return "Unknown=" + mLockScreenShown;
10080        }
10081    }
10082
10083    void logLockScreen(String msg) {
10084        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10085                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10086                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10087                + " mSleeping=" + mSleeping);
10088    }
10089
10090    void startRunningVoiceLocked() {
10091        if (!mRunningVoice) {
10092            mRunningVoice = true;
10093            updateSleepIfNeededLocked();
10094        }
10095    }
10096
10097    private void updateEventDispatchingLocked() {
10098        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10099    }
10100
10101    public void setLockScreenShown(boolean shown) {
10102        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10103                != PackageManager.PERMISSION_GRANTED) {
10104            throw new SecurityException("Requires permission "
10105                    + android.Manifest.permission.DEVICE_POWER);
10106        }
10107
10108        synchronized(this) {
10109            long ident = Binder.clearCallingIdentity();
10110            try {
10111                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10112                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10113                updateSleepIfNeededLocked();
10114            } finally {
10115                Binder.restoreCallingIdentity(ident);
10116            }
10117        }
10118    }
10119
10120    @Override
10121    public void stopAppSwitches() {
10122        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10123                != PackageManager.PERMISSION_GRANTED) {
10124            throw new SecurityException("Requires permission "
10125                    + android.Manifest.permission.STOP_APP_SWITCHES);
10126        }
10127
10128        synchronized(this) {
10129            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10130                    + APP_SWITCH_DELAY_TIME;
10131            mDidAppSwitch = false;
10132            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10133            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10134            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10135        }
10136    }
10137
10138    public void resumeAppSwitches() {
10139        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10140                != PackageManager.PERMISSION_GRANTED) {
10141            throw new SecurityException("Requires permission "
10142                    + android.Manifest.permission.STOP_APP_SWITCHES);
10143        }
10144
10145        synchronized(this) {
10146            // Note that we don't execute any pending app switches... we will
10147            // let those wait until either the timeout, or the next start
10148            // activity request.
10149            mAppSwitchesAllowedTime = 0;
10150        }
10151    }
10152
10153    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10154            int callingPid, int callingUid, String name) {
10155        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10156            return true;
10157        }
10158
10159        int perm = checkComponentPermission(
10160                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10161                sourceUid, -1, true);
10162        if (perm == PackageManager.PERMISSION_GRANTED) {
10163            return true;
10164        }
10165
10166        // If the actual IPC caller is different from the logical source, then
10167        // also see if they are allowed to control app switches.
10168        if (callingUid != -1 && callingUid != sourceUid) {
10169            perm = checkComponentPermission(
10170                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10171                    callingUid, -1, true);
10172            if (perm == PackageManager.PERMISSION_GRANTED) {
10173                return true;
10174            }
10175        }
10176
10177        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10178        return false;
10179    }
10180
10181    public void setDebugApp(String packageName, boolean waitForDebugger,
10182            boolean persistent) {
10183        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10184                "setDebugApp()");
10185
10186        long ident = Binder.clearCallingIdentity();
10187        try {
10188            // Note that this is not really thread safe if there are multiple
10189            // callers into it at the same time, but that's not a situation we
10190            // care about.
10191            if (persistent) {
10192                final ContentResolver resolver = mContext.getContentResolver();
10193                Settings.Global.putString(
10194                    resolver, Settings.Global.DEBUG_APP,
10195                    packageName);
10196                Settings.Global.putInt(
10197                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10198                    waitForDebugger ? 1 : 0);
10199            }
10200
10201            synchronized (this) {
10202                if (!persistent) {
10203                    mOrigDebugApp = mDebugApp;
10204                    mOrigWaitForDebugger = mWaitForDebugger;
10205                }
10206                mDebugApp = packageName;
10207                mWaitForDebugger = waitForDebugger;
10208                mDebugTransient = !persistent;
10209                if (packageName != null) {
10210                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10211                            false, UserHandle.USER_ALL, "set debug app");
10212                }
10213            }
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10220        synchronized (this) {
10221            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10222            if (!isDebuggable) {
10223                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10224                    throw new SecurityException("Process not debuggable: " + app.packageName);
10225                }
10226            }
10227
10228            mOpenGlTraceApp = processName;
10229        }
10230    }
10231
10232    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10233        synchronized (this) {
10234            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10235            if (!isDebuggable) {
10236                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10237                    throw new SecurityException("Process not debuggable: " + app.packageName);
10238                }
10239            }
10240            mProfileApp = processName;
10241            mProfileFile = profilerInfo.profileFile;
10242            if (mProfileFd != null) {
10243                try {
10244                    mProfileFd.close();
10245                } catch (IOException e) {
10246                }
10247                mProfileFd = null;
10248            }
10249            mProfileFd = profilerInfo.profileFd;
10250            mSamplingInterval = profilerInfo.samplingInterval;
10251            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10252            mProfileType = 0;
10253        }
10254    }
10255
10256    @Override
10257    public void setAlwaysFinish(boolean enabled) {
10258        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10259                "setAlwaysFinish()");
10260
10261        Settings.Global.putInt(
10262                mContext.getContentResolver(),
10263                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10264
10265        synchronized (this) {
10266            mAlwaysFinishActivities = enabled;
10267        }
10268    }
10269
10270    @Override
10271    public void setActivityController(IActivityController controller) {
10272        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10273                "setActivityController()");
10274        synchronized (this) {
10275            mController = controller;
10276            Watchdog.getInstance().setActivityController(controller);
10277        }
10278    }
10279
10280    @Override
10281    public void setUserIsMonkey(boolean userIsMonkey) {
10282        synchronized (this) {
10283            synchronized (mPidsSelfLocked) {
10284                final int callingPid = Binder.getCallingPid();
10285                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10286                if (precessRecord == null) {
10287                    throw new SecurityException("Unknown process: " + callingPid);
10288                }
10289                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10290                    throw new SecurityException("Only an instrumentation process "
10291                            + "with a UiAutomation can call setUserIsMonkey");
10292                }
10293            }
10294            mUserIsMonkey = userIsMonkey;
10295        }
10296    }
10297
10298    @Override
10299    public boolean isUserAMonkey() {
10300        synchronized (this) {
10301            // If there is a controller also implies the user is a monkey.
10302            return (mUserIsMonkey || mController != null);
10303        }
10304    }
10305
10306    public void requestBugReport() {
10307        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10308        SystemProperties.set("ctl.start", "bugreport");
10309    }
10310
10311    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10312        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10313    }
10314
10315    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10316        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10317            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10318        }
10319        return KEY_DISPATCHING_TIMEOUT;
10320    }
10321
10322    @Override
10323    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10324        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10325                != PackageManager.PERMISSION_GRANTED) {
10326            throw new SecurityException("Requires permission "
10327                    + android.Manifest.permission.FILTER_EVENTS);
10328        }
10329        ProcessRecord proc;
10330        long timeout;
10331        synchronized (this) {
10332            synchronized (mPidsSelfLocked) {
10333                proc = mPidsSelfLocked.get(pid);
10334            }
10335            timeout = getInputDispatchingTimeoutLocked(proc);
10336        }
10337
10338        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10339            return -1;
10340        }
10341
10342        return timeout;
10343    }
10344
10345    /**
10346     * Handle input dispatching timeouts.
10347     * Returns whether input dispatching should be aborted or not.
10348     */
10349    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10350            final ActivityRecord activity, final ActivityRecord parent,
10351            final boolean aboveSystem, String reason) {
10352        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10353                != PackageManager.PERMISSION_GRANTED) {
10354            throw new SecurityException("Requires permission "
10355                    + android.Manifest.permission.FILTER_EVENTS);
10356        }
10357
10358        final String annotation;
10359        if (reason == null) {
10360            annotation = "Input dispatching timed out";
10361        } else {
10362            annotation = "Input dispatching timed out (" + reason + ")";
10363        }
10364
10365        if (proc != null) {
10366            synchronized (this) {
10367                if (proc.debugging) {
10368                    return false;
10369                }
10370
10371                if (mDidDexOpt) {
10372                    // Give more time since we were dexopting.
10373                    mDidDexOpt = false;
10374                    return false;
10375                }
10376
10377                if (proc.instrumentationClass != null) {
10378                    Bundle info = new Bundle();
10379                    info.putString("shortMsg", "keyDispatchingTimedOut");
10380                    info.putString("longMsg", annotation);
10381                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10382                    return true;
10383                }
10384            }
10385            mHandler.post(new Runnable() {
10386                @Override
10387                public void run() {
10388                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10389                }
10390            });
10391        }
10392
10393        return true;
10394    }
10395
10396    public Bundle getAssistContextExtras(int requestType) {
10397        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10398                UserHandle.getCallingUserId());
10399        if (pae == null) {
10400            return null;
10401        }
10402        synchronized (pae) {
10403            while (!pae.haveResult) {
10404                try {
10405                    pae.wait();
10406                } catch (InterruptedException e) {
10407                }
10408            }
10409            if (pae.result != null) {
10410                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10411            }
10412        }
10413        synchronized (this) {
10414            mPendingAssistExtras.remove(pae);
10415            mHandler.removeCallbacks(pae);
10416        }
10417        return pae.extras;
10418    }
10419
10420    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10421            int userHandle) {
10422        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10423                "getAssistContextExtras()");
10424        PendingAssistExtras pae;
10425        Bundle extras = new Bundle();
10426        synchronized (this) {
10427            ActivityRecord activity = getFocusedStack().mResumedActivity;
10428            if (activity == null) {
10429                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10430                return null;
10431            }
10432            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10433            if (activity.app == null || activity.app.thread == null) {
10434                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10435                return null;
10436            }
10437            if (activity.app.pid == Binder.getCallingPid()) {
10438                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10439                return null;
10440            }
10441            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10442            try {
10443                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10444                        requestType);
10445                mPendingAssistExtras.add(pae);
10446                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10447            } catch (RemoteException e) {
10448                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10449                return null;
10450            }
10451            return pae;
10452        }
10453    }
10454
10455    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10456        PendingAssistExtras pae = (PendingAssistExtras)token;
10457        synchronized (pae) {
10458            pae.result = extras;
10459            pae.haveResult = true;
10460            pae.notifyAll();
10461            if (pae.intent == null) {
10462                // Caller is just waiting for the result.
10463                return;
10464            }
10465        }
10466
10467        // We are now ready to launch the assist activity.
10468        synchronized (this) {
10469            boolean exists = mPendingAssistExtras.remove(pae);
10470            mHandler.removeCallbacks(pae);
10471            if (!exists) {
10472                // Timed out.
10473                return;
10474            }
10475        }
10476        pae.intent.replaceExtras(extras);
10477        if (pae.hint != null) {
10478            pae.intent.putExtra(pae.hint, true);
10479        }
10480        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10481                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10482                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10483        closeSystemDialogs("assist");
10484        try {
10485            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10486        } catch (ActivityNotFoundException e) {
10487            Slog.w(TAG, "No activity to handle assist action.", e);
10488        }
10489    }
10490
10491    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10492        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10493    }
10494
10495    public void registerProcessObserver(IProcessObserver observer) {
10496        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10497                "registerProcessObserver()");
10498        synchronized (this) {
10499            mProcessObservers.register(observer);
10500        }
10501    }
10502
10503    @Override
10504    public void unregisterProcessObserver(IProcessObserver observer) {
10505        synchronized (this) {
10506            mProcessObservers.unregister(observer);
10507        }
10508    }
10509
10510    @Override
10511    public boolean convertFromTranslucent(IBinder token) {
10512        final long origId = Binder.clearCallingIdentity();
10513        try {
10514            synchronized (this) {
10515                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10516                if (r == null) {
10517                    return false;
10518                }
10519                final boolean translucentChanged = r.changeWindowTranslucency(true);
10520                if (translucentChanged) {
10521                    r.task.stack.releaseBackgroundResources();
10522                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10523                }
10524                mWindowManager.setAppFullscreen(token, true);
10525                return translucentChanged;
10526            }
10527        } finally {
10528            Binder.restoreCallingIdentity(origId);
10529        }
10530    }
10531
10532    @Override
10533    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10534        final long origId = Binder.clearCallingIdentity();
10535        try {
10536            synchronized (this) {
10537                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10538                if (r == null) {
10539                    return false;
10540                }
10541                int index = r.task.mActivities.lastIndexOf(r);
10542                if (index > 0) {
10543                    ActivityRecord under = r.task.mActivities.get(index - 1);
10544                    under.returningOptions = options;
10545                }
10546                final boolean translucentChanged = r.changeWindowTranslucency(false);
10547                if (translucentChanged) {
10548                    r.task.stack.convertToTranslucent(r);
10549                }
10550                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10551                mWindowManager.setAppFullscreen(token, false);
10552                return translucentChanged;
10553            }
10554        } finally {
10555            Binder.restoreCallingIdentity(origId);
10556        }
10557    }
10558
10559    @Override
10560    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10561        final long origId = Binder.clearCallingIdentity();
10562        try {
10563            synchronized (this) {
10564                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10565                if (r != null) {
10566                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10567                }
10568            }
10569            return false;
10570        } finally {
10571            Binder.restoreCallingIdentity(origId);
10572        }
10573    }
10574
10575    @Override
10576    public boolean isBackgroundVisibleBehind(IBinder token) {
10577        final long origId = Binder.clearCallingIdentity();
10578        try {
10579            synchronized (this) {
10580                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10581                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10582                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10583                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10584                return visible;
10585            }
10586        } finally {
10587            Binder.restoreCallingIdentity(origId);
10588        }
10589    }
10590
10591    @Override
10592    public ActivityOptions getActivityOptions(IBinder token) {
10593        final long origId = Binder.clearCallingIdentity();
10594        try {
10595            synchronized (this) {
10596                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10597                if (r != null) {
10598                    final ActivityOptions activityOptions = r.pendingOptions;
10599                    r.pendingOptions = null;
10600                    return activityOptions;
10601                }
10602                return null;
10603            }
10604        } finally {
10605            Binder.restoreCallingIdentity(origId);
10606        }
10607    }
10608
10609    @Override
10610    public void setImmersive(IBinder token, boolean immersive) {
10611        synchronized(this) {
10612            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10613            if (r == null) {
10614                throw new IllegalArgumentException();
10615            }
10616            r.immersive = immersive;
10617
10618            // update associated state if we're frontmost
10619            if (r == mFocusedActivity) {
10620                if (DEBUG_IMMERSIVE) {
10621                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10622                }
10623                applyUpdateLockStateLocked(r);
10624            }
10625        }
10626    }
10627
10628    @Override
10629    public boolean isImmersive(IBinder token) {
10630        synchronized (this) {
10631            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10632            if (r == null) {
10633                throw new IllegalArgumentException();
10634            }
10635            return r.immersive;
10636        }
10637    }
10638
10639    public boolean isTopActivityImmersive() {
10640        enforceNotIsolatedCaller("startActivity");
10641        synchronized (this) {
10642            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10643            return (r != null) ? r.immersive : false;
10644        }
10645    }
10646
10647    @Override
10648    public boolean isTopOfTask(IBinder token) {
10649        synchronized (this) {
10650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10651            if (r == null) {
10652                throw new IllegalArgumentException();
10653            }
10654            return r.task.getTopActivity() == r;
10655        }
10656    }
10657
10658    public final void enterSafeMode() {
10659        synchronized(this) {
10660            // It only makes sense to do this before the system is ready
10661            // and started launching other packages.
10662            if (!mSystemReady) {
10663                try {
10664                    AppGlobals.getPackageManager().enterSafeMode();
10665                } catch (RemoteException e) {
10666                }
10667            }
10668
10669            mSafeMode = true;
10670        }
10671    }
10672
10673    public final void showSafeModeOverlay() {
10674        View v = LayoutInflater.from(mContext).inflate(
10675                com.android.internal.R.layout.safe_mode, null);
10676        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10677        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10678        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10679        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10680        lp.gravity = Gravity.BOTTOM | Gravity.START;
10681        lp.format = v.getBackground().getOpacity();
10682        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10683                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10684        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10685        ((WindowManager)mContext.getSystemService(
10686                Context.WINDOW_SERVICE)).addView(v, lp);
10687    }
10688
10689    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10690        if (!(sender instanceof PendingIntentRecord)) {
10691            return;
10692        }
10693        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10694        synchronized (stats) {
10695            if (mBatteryStatsService.isOnBattery()) {
10696                mBatteryStatsService.enforceCallingPermission();
10697                PendingIntentRecord rec = (PendingIntentRecord)sender;
10698                int MY_UID = Binder.getCallingUid();
10699                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10700                BatteryStatsImpl.Uid.Pkg pkg =
10701                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10702                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10703                pkg.incWakeupsLocked();
10704            }
10705        }
10706    }
10707
10708    public boolean killPids(int[] pids, String pReason, boolean secure) {
10709        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10710            throw new SecurityException("killPids only available to the system");
10711        }
10712        String reason = (pReason == null) ? "Unknown" : pReason;
10713        // XXX Note: don't acquire main activity lock here, because the window
10714        // manager calls in with its locks held.
10715
10716        boolean killed = false;
10717        synchronized (mPidsSelfLocked) {
10718            int[] types = new int[pids.length];
10719            int worstType = 0;
10720            for (int i=0; i<pids.length; i++) {
10721                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10722                if (proc != null) {
10723                    int type = proc.setAdj;
10724                    types[i] = type;
10725                    if (type > worstType) {
10726                        worstType = type;
10727                    }
10728                }
10729            }
10730
10731            // If the worst oom_adj is somewhere in the cached proc LRU range,
10732            // then constrain it so we will kill all cached procs.
10733            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10734                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10735                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10736            }
10737
10738            // If this is not a secure call, don't let it kill processes that
10739            // are important.
10740            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10741                worstType = ProcessList.SERVICE_ADJ;
10742            }
10743
10744            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10745            for (int i=0; i<pids.length; i++) {
10746                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10747                if (proc == null) {
10748                    continue;
10749                }
10750                int adj = proc.setAdj;
10751                if (adj >= worstType && !proc.killedByAm) {
10752                    proc.kill(reason, true);
10753                    killed = true;
10754                }
10755            }
10756        }
10757        return killed;
10758    }
10759
10760    @Override
10761    public void killUid(int uid, String reason) {
10762        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10763            throw new SecurityException("killUid only available to the system");
10764        }
10765        synchronized (this) {
10766            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10767                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10768                    reason != null ? reason : "kill uid");
10769        }
10770    }
10771
10772    @Override
10773    public boolean killProcessesBelowForeground(String reason) {
10774        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10775            throw new SecurityException("killProcessesBelowForeground() only available to system");
10776        }
10777
10778        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10779    }
10780
10781    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10782        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10783            throw new SecurityException("killProcessesBelowAdj() only available to system");
10784        }
10785
10786        boolean killed = false;
10787        synchronized (mPidsSelfLocked) {
10788            final int size = mPidsSelfLocked.size();
10789            for (int i = 0; i < size; i++) {
10790                final int pid = mPidsSelfLocked.keyAt(i);
10791                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10792                if (proc == null) continue;
10793
10794                final int adj = proc.setAdj;
10795                if (adj > belowAdj && !proc.killedByAm) {
10796                    proc.kill(reason, true);
10797                    killed = true;
10798                }
10799            }
10800        }
10801        return killed;
10802    }
10803
10804    @Override
10805    public void hang(final IBinder who, boolean allowRestart) {
10806        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10807                != PackageManager.PERMISSION_GRANTED) {
10808            throw new SecurityException("Requires permission "
10809                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10810        }
10811
10812        final IBinder.DeathRecipient death = new DeathRecipient() {
10813            @Override
10814            public void binderDied() {
10815                synchronized (this) {
10816                    notifyAll();
10817                }
10818            }
10819        };
10820
10821        try {
10822            who.linkToDeath(death, 0);
10823        } catch (RemoteException e) {
10824            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10825            return;
10826        }
10827
10828        synchronized (this) {
10829            Watchdog.getInstance().setAllowRestart(allowRestart);
10830            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10831            synchronized (death) {
10832                while (who.isBinderAlive()) {
10833                    try {
10834                        death.wait();
10835                    } catch (InterruptedException e) {
10836                    }
10837                }
10838            }
10839            Watchdog.getInstance().setAllowRestart(true);
10840        }
10841    }
10842
10843    @Override
10844    public void restart() {
10845        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10846                != PackageManager.PERMISSION_GRANTED) {
10847            throw new SecurityException("Requires permission "
10848                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10849        }
10850
10851        Log.i(TAG, "Sending shutdown broadcast...");
10852
10853        BroadcastReceiver br = new BroadcastReceiver() {
10854            @Override public void onReceive(Context context, Intent intent) {
10855                // Now the broadcast is done, finish up the low-level shutdown.
10856                Log.i(TAG, "Shutting down activity manager...");
10857                shutdown(10000);
10858                Log.i(TAG, "Shutdown complete, restarting!");
10859                Process.killProcess(Process.myPid());
10860                System.exit(10);
10861            }
10862        };
10863
10864        // First send the high-level shut down broadcast.
10865        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10866        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10867        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10868        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10869        mContext.sendOrderedBroadcastAsUser(intent,
10870                UserHandle.ALL, null, br, mHandler, 0, null, null);
10871        */
10872        br.onReceive(mContext, intent);
10873    }
10874
10875    private long getLowRamTimeSinceIdle(long now) {
10876        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10877    }
10878
10879    @Override
10880    public void performIdleMaintenance() {
10881        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10882                != PackageManager.PERMISSION_GRANTED) {
10883            throw new SecurityException("Requires permission "
10884                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10885        }
10886
10887        synchronized (this) {
10888            final long now = SystemClock.uptimeMillis();
10889            final long timeSinceLastIdle = now - mLastIdleTime;
10890            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10891            mLastIdleTime = now;
10892            mLowRamTimeSinceLastIdle = 0;
10893            if (mLowRamStartTime != 0) {
10894                mLowRamStartTime = now;
10895            }
10896
10897            StringBuilder sb = new StringBuilder(128);
10898            sb.append("Idle maintenance over ");
10899            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10900            sb.append(" low RAM for ");
10901            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10902            Slog.i(TAG, sb.toString());
10903
10904            // If at least 1/3 of our time since the last idle period has been spent
10905            // with RAM low, then we want to kill processes.
10906            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10907
10908            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10909                ProcessRecord proc = mLruProcesses.get(i);
10910                if (proc.notCachedSinceIdle) {
10911                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10912                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10913                        if (doKilling && proc.initialIdlePss != 0
10914                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10915                            proc.kill("idle maint (pss " + proc.lastPss
10916                                    + " from " + proc.initialIdlePss + ")", true);
10917                        }
10918                    }
10919                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10920                    proc.notCachedSinceIdle = true;
10921                    proc.initialIdlePss = 0;
10922                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10923                            isSleeping(), now);
10924                }
10925            }
10926
10927            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10928            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10929        }
10930    }
10931
10932    private void retrieveSettings() {
10933        final ContentResolver resolver = mContext.getContentResolver();
10934        String debugApp = Settings.Global.getString(
10935            resolver, Settings.Global.DEBUG_APP);
10936        boolean waitForDebugger = Settings.Global.getInt(
10937            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10938        boolean alwaysFinishActivities = Settings.Global.getInt(
10939            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10940        boolean forceRtl = Settings.Global.getInt(
10941                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10942        // Transfer any global setting for forcing RTL layout, into a System Property
10943        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10944
10945        Configuration configuration = new Configuration();
10946        Settings.System.getConfiguration(resolver, configuration);
10947        if (forceRtl) {
10948            // This will take care of setting the correct layout direction flags
10949            configuration.setLayoutDirection(configuration.locale);
10950        }
10951
10952        synchronized (this) {
10953            mDebugApp = mOrigDebugApp = debugApp;
10954            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10955            mAlwaysFinishActivities = alwaysFinishActivities;
10956            // This happens before any activities are started, so we can
10957            // change mConfiguration in-place.
10958            updateConfigurationLocked(configuration, null, false, true);
10959            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10960        }
10961    }
10962
10963    /** Loads resources after the current configuration has been set. */
10964    private void loadResourcesOnSystemReady() {
10965        final Resources res = mContext.getResources();
10966        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10967        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10968        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10969    }
10970
10971    public boolean testIsSystemReady() {
10972        // no need to synchronize(this) just to read & return the value
10973        return mSystemReady;
10974    }
10975
10976    private static File getCalledPreBootReceiversFile() {
10977        File dataDir = Environment.getDataDirectory();
10978        File systemDir = new File(dataDir, "system");
10979        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10980        return fname;
10981    }
10982
10983    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10984        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10985        File file = getCalledPreBootReceiversFile();
10986        FileInputStream fis = null;
10987        try {
10988            fis = new FileInputStream(file);
10989            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10990            int fvers = dis.readInt();
10991            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10992                String vers = dis.readUTF();
10993                String codename = dis.readUTF();
10994                String build = dis.readUTF();
10995                if (android.os.Build.VERSION.RELEASE.equals(vers)
10996                        && android.os.Build.VERSION.CODENAME.equals(codename)
10997                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10998                    int num = dis.readInt();
10999                    while (num > 0) {
11000                        num--;
11001                        String pkg = dis.readUTF();
11002                        String cls = dis.readUTF();
11003                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11004                    }
11005                }
11006            }
11007        } catch (FileNotFoundException e) {
11008        } catch (IOException e) {
11009            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11010        } finally {
11011            if (fis != null) {
11012                try {
11013                    fis.close();
11014                } catch (IOException e) {
11015                }
11016            }
11017        }
11018        return lastDoneReceivers;
11019    }
11020
11021    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11022        File file = getCalledPreBootReceiversFile();
11023        FileOutputStream fos = null;
11024        DataOutputStream dos = null;
11025        try {
11026            fos = new FileOutputStream(file);
11027            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11028            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11029            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11030            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11031            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11032            dos.writeInt(list.size());
11033            for (int i=0; i<list.size(); i++) {
11034                dos.writeUTF(list.get(i).getPackageName());
11035                dos.writeUTF(list.get(i).getClassName());
11036            }
11037        } catch (IOException e) {
11038            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11039            file.delete();
11040        } finally {
11041            FileUtils.sync(fos);
11042            if (dos != null) {
11043                try {
11044                    dos.close();
11045                } catch (IOException e) {
11046                    // TODO Auto-generated catch block
11047                    e.printStackTrace();
11048                }
11049            }
11050        }
11051    }
11052
11053    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11054            ArrayList<ComponentName> doneReceivers, int userId) {
11055        boolean waitingUpdate = false;
11056        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11057        List<ResolveInfo> ris = null;
11058        try {
11059            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11060                    intent, null, 0, userId);
11061        } catch (RemoteException e) {
11062        }
11063        if (ris != null) {
11064            for (int i=ris.size()-1; i>=0; i--) {
11065                if ((ris.get(i).activityInfo.applicationInfo.flags
11066                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11067                    ris.remove(i);
11068                }
11069            }
11070            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11071
11072            // For User 0, load the version number. When delivering to a new user, deliver
11073            // to all receivers.
11074            if (userId == UserHandle.USER_OWNER) {
11075                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11076                for (int i=0; i<ris.size(); i++) {
11077                    ActivityInfo ai = ris.get(i).activityInfo;
11078                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11079                    if (lastDoneReceivers.contains(comp)) {
11080                        // We already did the pre boot receiver for this app with the current
11081                        // platform version, so don't do it again...
11082                        ris.remove(i);
11083                        i--;
11084                        // ...however, do keep it as one that has been done, so we don't
11085                        // forget about it when rewriting the file of last done receivers.
11086                        doneReceivers.add(comp);
11087                    }
11088                }
11089            }
11090
11091            // If primary user, send broadcast to all available users, else just to userId
11092            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11093                    : new int[] { userId };
11094            for (int i = 0; i < ris.size(); i++) {
11095                ActivityInfo ai = ris.get(i).activityInfo;
11096                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11097                doneReceivers.add(comp);
11098                intent.setComponent(comp);
11099                for (int j=0; j<users.length; j++) {
11100                    IIntentReceiver finisher = null;
11101                    // On last receiver and user, set up a completion callback
11102                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11103                        finisher = new IIntentReceiver.Stub() {
11104                            public void performReceive(Intent intent, int resultCode,
11105                                    String data, Bundle extras, boolean ordered,
11106                                    boolean sticky, int sendingUser) {
11107                                // The raw IIntentReceiver interface is called
11108                                // with the AM lock held, so redispatch to
11109                                // execute our code without the lock.
11110                                mHandler.post(onFinishCallback);
11111                            }
11112                        };
11113                    }
11114                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11115                            + " for user " + users[j]);
11116                    broadcastIntentLocked(null, null, intent, null, finisher,
11117                            0, null, null, null, AppOpsManager.OP_NONE,
11118                            true, false, MY_PID, Process.SYSTEM_UID,
11119                            users[j]);
11120                    if (finisher != null) {
11121                        waitingUpdate = true;
11122                    }
11123                }
11124            }
11125        }
11126
11127        return waitingUpdate;
11128    }
11129
11130    public void systemReady(final Runnable goingCallback) {
11131        synchronized(this) {
11132            if (mSystemReady) {
11133                // If we're done calling all the receivers, run the next "boot phase" passed in
11134                // by the SystemServer
11135                if (goingCallback != null) {
11136                    goingCallback.run();
11137                }
11138                return;
11139            }
11140
11141            // Make sure we have the current profile info, since it is needed for
11142            // security checks.
11143            updateCurrentProfileIdsLocked();
11144
11145            if (mRecentTasks == null) {
11146                mRecentTasks = mTaskPersister.restoreTasksLocked();
11147                if (!mRecentTasks.isEmpty()) {
11148                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11149                }
11150                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11151                mTaskPersister.startPersisting();
11152            }
11153
11154            // Check to see if there are any update receivers to run.
11155            if (!mDidUpdate) {
11156                if (mWaitingUpdate) {
11157                    return;
11158                }
11159                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11160                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11161                    public void run() {
11162                        synchronized (ActivityManagerService.this) {
11163                            mDidUpdate = true;
11164                        }
11165                        writeLastDonePreBootReceivers(doneReceivers);
11166                        showBootMessage(mContext.getText(
11167                                R.string.android_upgrading_complete),
11168                                false);
11169                        systemReady(goingCallback);
11170                    }
11171                }, doneReceivers, UserHandle.USER_OWNER);
11172
11173                if (mWaitingUpdate) {
11174                    return;
11175                }
11176                mDidUpdate = true;
11177            }
11178
11179            mAppOpsService.systemReady();
11180            mSystemReady = true;
11181        }
11182
11183        ArrayList<ProcessRecord> procsToKill = null;
11184        synchronized(mPidsSelfLocked) {
11185            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11186                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11187                if (!isAllowedWhileBooting(proc.info)){
11188                    if (procsToKill == null) {
11189                        procsToKill = new ArrayList<ProcessRecord>();
11190                    }
11191                    procsToKill.add(proc);
11192                }
11193            }
11194        }
11195
11196        synchronized(this) {
11197            if (procsToKill != null) {
11198                for (int i=procsToKill.size()-1; i>=0; i--) {
11199                    ProcessRecord proc = procsToKill.get(i);
11200                    Slog.i(TAG, "Removing system update proc: " + proc);
11201                    removeProcessLocked(proc, true, false, "system update done");
11202                }
11203            }
11204
11205            // Now that we have cleaned up any update processes, we
11206            // are ready to start launching real processes and know that
11207            // we won't trample on them any more.
11208            mProcessesReady = true;
11209        }
11210
11211        Slog.i(TAG, "System now ready");
11212        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11213            SystemClock.uptimeMillis());
11214
11215        synchronized(this) {
11216            // Make sure we have no pre-ready processes sitting around.
11217
11218            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11219                ResolveInfo ri = mContext.getPackageManager()
11220                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11221                                STOCK_PM_FLAGS);
11222                CharSequence errorMsg = null;
11223                if (ri != null) {
11224                    ActivityInfo ai = ri.activityInfo;
11225                    ApplicationInfo app = ai.applicationInfo;
11226                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11227                        mTopAction = Intent.ACTION_FACTORY_TEST;
11228                        mTopData = null;
11229                        mTopComponent = new ComponentName(app.packageName,
11230                                ai.name);
11231                    } else {
11232                        errorMsg = mContext.getResources().getText(
11233                                com.android.internal.R.string.factorytest_not_system);
11234                    }
11235                } else {
11236                    errorMsg = mContext.getResources().getText(
11237                            com.android.internal.R.string.factorytest_no_action);
11238                }
11239                if (errorMsg != null) {
11240                    mTopAction = null;
11241                    mTopData = null;
11242                    mTopComponent = null;
11243                    Message msg = Message.obtain();
11244                    msg.what = SHOW_FACTORY_ERROR_MSG;
11245                    msg.getData().putCharSequence("msg", errorMsg);
11246                    mHandler.sendMessage(msg);
11247                }
11248            }
11249        }
11250
11251        retrieveSettings();
11252        loadResourcesOnSystemReady();
11253
11254        synchronized (this) {
11255            readGrantedUriPermissionsLocked();
11256        }
11257
11258        if (goingCallback != null) goingCallback.run();
11259
11260        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11261                Integer.toString(mCurrentUserId), mCurrentUserId);
11262        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11263                Integer.toString(mCurrentUserId), mCurrentUserId);
11264        mSystemServiceManager.startUser(mCurrentUserId);
11265
11266        synchronized (this) {
11267            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11268                try {
11269                    List apps = AppGlobals.getPackageManager().
11270                        getPersistentApplications(STOCK_PM_FLAGS);
11271                    if (apps != null) {
11272                        int N = apps.size();
11273                        int i;
11274                        for (i=0; i<N; i++) {
11275                            ApplicationInfo info
11276                                = (ApplicationInfo)apps.get(i);
11277                            if (info != null &&
11278                                    !info.packageName.equals("android")) {
11279                                addAppLocked(info, false, null /* ABI override */);
11280                            }
11281                        }
11282                    }
11283                } catch (RemoteException ex) {
11284                    // pm is in same process, this will never happen.
11285                }
11286            }
11287
11288            // Start up initial activity.
11289            mBooting = true;
11290            startHomeActivityLocked(mCurrentUserId);
11291
11292            try {
11293                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11294                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11295                            + " data partition or your device will be unstable.");
11296                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11297                }
11298            } catch (RemoteException e) {
11299            }
11300
11301            if (!Build.isFingerprintConsistent()) {
11302                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11303                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11304            }
11305
11306            long ident = Binder.clearCallingIdentity();
11307            try {
11308                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11309                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11310                        | Intent.FLAG_RECEIVER_FOREGROUND);
11311                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11312                broadcastIntentLocked(null, null, intent,
11313                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11314                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11315                intent = new Intent(Intent.ACTION_USER_STARTING);
11316                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11317                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11318                broadcastIntentLocked(null, null, intent,
11319                        null, new IIntentReceiver.Stub() {
11320                            @Override
11321                            public void performReceive(Intent intent, int resultCode, String data,
11322                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11323                                    throws RemoteException {
11324                            }
11325                        }, 0, null, null,
11326                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11327                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11328            } catch (Throwable t) {
11329                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11330            } finally {
11331                Binder.restoreCallingIdentity(ident);
11332            }
11333            mStackSupervisor.resumeTopActivitiesLocked();
11334            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11335        }
11336    }
11337
11338    private boolean makeAppCrashingLocked(ProcessRecord app,
11339            String shortMsg, String longMsg, String stackTrace) {
11340        app.crashing = true;
11341        app.crashingReport = generateProcessError(app,
11342                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11343        startAppProblemLocked(app);
11344        app.stopFreezingAllLocked();
11345        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11346    }
11347
11348    private void makeAppNotRespondingLocked(ProcessRecord app,
11349            String activity, String shortMsg, String longMsg) {
11350        app.notResponding = true;
11351        app.notRespondingReport = generateProcessError(app,
11352                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11353                activity, shortMsg, longMsg, null);
11354        startAppProblemLocked(app);
11355        app.stopFreezingAllLocked();
11356    }
11357
11358    /**
11359     * Generate a process error record, suitable for attachment to a ProcessRecord.
11360     *
11361     * @param app The ProcessRecord in which the error occurred.
11362     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11363     *                      ActivityManager.AppErrorStateInfo
11364     * @param activity The activity associated with the crash, if known.
11365     * @param shortMsg Short message describing the crash.
11366     * @param longMsg Long message describing the crash.
11367     * @param stackTrace Full crash stack trace, may be null.
11368     *
11369     * @return Returns a fully-formed AppErrorStateInfo record.
11370     */
11371    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11372            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11373        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11374
11375        report.condition = condition;
11376        report.processName = app.processName;
11377        report.pid = app.pid;
11378        report.uid = app.info.uid;
11379        report.tag = activity;
11380        report.shortMsg = shortMsg;
11381        report.longMsg = longMsg;
11382        report.stackTrace = stackTrace;
11383
11384        return report;
11385    }
11386
11387    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11388        synchronized (this) {
11389            app.crashing = false;
11390            app.crashingReport = null;
11391            app.notResponding = false;
11392            app.notRespondingReport = null;
11393            if (app.anrDialog == fromDialog) {
11394                app.anrDialog = null;
11395            }
11396            if (app.waitDialog == fromDialog) {
11397                app.waitDialog = null;
11398            }
11399            if (app.pid > 0 && app.pid != MY_PID) {
11400                handleAppCrashLocked(app, null, null, null);
11401                app.kill("user request after error", true);
11402            }
11403        }
11404    }
11405
11406    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11407            String stackTrace) {
11408        long now = SystemClock.uptimeMillis();
11409
11410        Long crashTime;
11411        if (!app.isolated) {
11412            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11413        } else {
11414            crashTime = null;
11415        }
11416        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11417            // This process loses!
11418            Slog.w(TAG, "Process " + app.info.processName
11419                    + " has crashed too many times: killing!");
11420            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11421                    app.userId, app.info.processName, app.uid);
11422            mStackSupervisor.handleAppCrashLocked(app);
11423            if (!app.persistent) {
11424                // We don't want to start this process again until the user
11425                // explicitly does so...  but for persistent process, we really
11426                // need to keep it running.  If a persistent process is actually
11427                // repeatedly crashing, then badness for everyone.
11428                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11429                        app.info.processName);
11430                if (!app.isolated) {
11431                    // XXX We don't have a way to mark isolated processes
11432                    // as bad, since they don't have a peristent identity.
11433                    mBadProcesses.put(app.info.processName, app.uid,
11434                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11435                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11436                }
11437                app.bad = true;
11438                app.removed = true;
11439                // Don't let services in this process be restarted and potentially
11440                // annoy the user repeatedly.  Unless it is persistent, since those
11441                // processes run critical code.
11442                removeProcessLocked(app, false, false, "crash");
11443                mStackSupervisor.resumeTopActivitiesLocked();
11444                return false;
11445            }
11446            mStackSupervisor.resumeTopActivitiesLocked();
11447        } else {
11448            mStackSupervisor.finishTopRunningActivityLocked(app);
11449        }
11450
11451        // Bump up the crash count of any services currently running in the proc.
11452        for (int i=app.services.size()-1; i>=0; i--) {
11453            // Any services running in the application need to be placed
11454            // back in the pending list.
11455            ServiceRecord sr = app.services.valueAt(i);
11456            sr.crashCount++;
11457        }
11458
11459        // If the crashing process is what we consider to be the "home process" and it has been
11460        // replaced by a third-party app, clear the package preferred activities from packages
11461        // with a home activity running in the process to prevent a repeatedly crashing app
11462        // from blocking the user to manually clear the list.
11463        final ArrayList<ActivityRecord> activities = app.activities;
11464        if (app == mHomeProcess && activities.size() > 0
11465                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11466            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11467                final ActivityRecord r = activities.get(activityNdx);
11468                if (r.isHomeActivity()) {
11469                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11470                    try {
11471                        ActivityThread.getPackageManager()
11472                                .clearPackagePreferredActivities(r.packageName);
11473                    } catch (RemoteException c) {
11474                        // pm is in same process, this will never happen.
11475                    }
11476                }
11477            }
11478        }
11479
11480        if (!app.isolated) {
11481            // XXX Can't keep track of crash times for isolated processes,
11482            // because they don't have a perisistent identity.
11483            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11484        }
11485
11486        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11487        return true;
11488    }
11489
11490    void startAppProblemLocked(ProcessRecord app) {
11491        // If this app is not running under the current user, then we
11492        // can't give it a report button because that would require
11493        // launching the report UI under a different user.
11494        app.errorReportReceiver = null;
11495
11496        for (int userId : mCurrentProfileIds) {
11497            if (app.userId == userId) {
11498                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11499                        mContext, app.info.packageName, app.info.flags);
11500            }
11501        }
11502        skipCurrentReceiverLocked(app);
11503    }
11504
11505    void skipCurrentReceiverLocked(ProcessRecord app) {
11506        for (BroadcastQueue queue : mBroadcastQueues) {
11507            queue.skipCurrentReceiverLocked(app);
11508        }
11509    }
11510
11511    /**
11512     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11513     * The application process will exit immediately after this call returns.
11514     * @param app object of the crashing app, null for the system server
11515     * @param crashInfo describing the exception
11516     */
11517    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11518        ProcessRecord r = findAppProcess(app, "Crash");
11519        final String processName = app == null ? "system_server"
11520                : (r == null ? "unknown" : r.processName);
11521
11522        handleApplicationCrashInner("crash", r, processName, crashInfo);
11523    }
11524
11525    /* Native crash reporting uses this inner version because it needs to be somewhat
11526     * decoupled from the AM-managed cleanup lifecycle
11527     */
11528    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11529            ApplicationErrorReport.CrashInfo crashInfo) {
11530        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11531                UserHandle.getUserId(Binder.getCallingUid()), processName,
11532                r == null ? -1 : r.info.flags,
11533                crashInfo.exceptionClassName,
11534                crashInfo.exceptionMessage,
11535                crashInfo.throwFileName,
11536                crashInfo.throwLineNumber);
11537
11538        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11539
11540        crashApplication(r, crashInfo);
11541    }
11542
11543    public void handleApplicationStrictModeViolation(
11544            IBinder app,
11545            int violationMask,
11546            StrictMode.ViolationInfo info) {
11547        ProcessRecord r = findAppProcess(app, "StrictMode");
11548        if (r == null) {
11549            return;
11550        }
11551
11552        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11553            Integer stackFingerprint = info.hashCode();
11554            boolean logIt = true;
11555            synchronized (mAlreadyLoggedViolatedStacks) {
11556                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11557                    logIt = false;
11558                    // TODO: sub-sample into EventLog for these, with
11559                    // the info.durationMillis?  Then we'd get
11560                    // the relative pain numbers, without logging all
11561                    // the stack traces repeatedly.  We'd want to do
11562                    // likewise in the client code, which also does
11563                    // dup suppression, before the Binder call.
11564                } else {
11565                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11566                        mAlreadyLoggedViolatedStacks.clear();
11567                    }
11568                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11569                }
11570            }
11571            if (logIt) {
11572                logStrictModeViolationToDropBox(r, info);
11573            }
11574        }
11575
11576        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11577            AppErrorResult result = new AppErrorResult();
11578            synchronized (this) {
11579                final long origId = Binder.clearCallingIdentity();
11580
11581                Message msg = Message.obtain();
11582                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11583                HashMap<String, Object> data = new HashMap<String, Object>();
11584                data.put("result", result);
11585                data.put("app", r);
11586                data.put("violationMask", violationMask);
11587                data.put("info", info);
11588                msg.obj = data;
11589                mHandler.sendMessage(msg);
11590
11591                Binder.restoreCallingIdentity(origId);
11592            }
11593            int res = result.get();
11594            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11595        }
11596    }
11597
11598    // Depending on the policy in effect, there could be a bunch of
11599    // these in quick succession so we try to batch these together to
11600    // minimize disk writes, number of dropbox entries, and maximize
11601    // compression, by having more fewer, larger records.
11602    private void logStrictModeViolationToDropBox(
11603            ProcessRecord process,
11604            StrictMode.ViolationInfo info) {
11605        if (info == null) {
11606            return;
11607        }
11608        final boolean isSystemApp = process == null ||
11609                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11610                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11611        final String processName = process == null ? "unknown" : process.processName;
11612        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11613        final DropBoxManager dbox = (DropBoxManager)
11614                mContext.getSystemService(Context.DROPBOX_SERVICE);
11615
11616        // Exit early if the dropbox isn't configured to accept this report type.
11617        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11618
11619        boolean bufferWasEmpty;
11620        boolean needsFlush;
11621        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11622        synchronized (sb) {
11623            bufferWasEmpty = sb.length() == 0;
11624            appendDropBoxProcessHeaders(process, processName, sb);
11625            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11626            sb.append("System-App: ").append(isSystemApp).append("\n");
11627            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11628            if (info.violationNumThisLoop != 0) {
11629                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11630            }
11631            if (info.numAnimationsRunning != 0) {
11632                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11633            }
11634            if (info.broadcastIntentAction != null) {
11635                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11636            }
11637            if (info.durationMillis != -1) {
11638                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11639            }
11640            if (info.numInstances != -1) {
11641                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11642            }
11643            if (info.tags != null) {
11644                for (String tag : info.tags) {
11645                    sb.append("Span-Tag: ").append(tag).append("\n");
11646                }
11647            }
11648            sb.append("\n");
11649            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11650                sb.append(info.crashInfo.stackTrace);
11651            }
11652            sb.append("\n");
11653
11654            // Only buffer up to ~64k.  Various logging bits truncate
11655            // things at 128k.
11656            needsFlush = (sb.length() > 64 * 1024);
11657        }
11658
11659        // Flush immediately if the buffer's grown too large, or this
11660        // is a non-system app.  Non-system apps are isolated with a
11661        // different tag & policy and not batched.
11662        //
11663        // Batching is useful during internal testing with
11664        // StrictMode settings turned up high.  Without batching,
11665        // thousands of separate files could be created on boot.
11666        if (!isSystemApp || needsFlush) {
11667            new Thread("Error dump: " + dropboxTag) {
11668                @Override
11669                public void run() {
11670                    String report;
11671                    synchronized (sb) {
11672                        report = sb.toString();
11673                        sb.delete(0, sb.length());
11674                        sb.trimToSize();
11675                    }
11676                    if (report.length() != 0) {
11677                        dbox.addText(dropboxTag, report);
11678                    }
11679                }
11680            }.start();
11681            return;
11682        }
11683
11684        // System app batching:
11685        if (!bufferWasEmpty) {
11686            // An existing dropbox-writing thread is outstanding, so
11687            // we don't need to start it up.  The existing thread will
11688            // catch the buffer appends we just did.
11689            return;
11690        }
11691
11692        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11693        // (After this point, we shouldn't access AMS internal data structures.)
11694        new Thread("Error dump: " + dropboxTag) {
11695            @Override
11696            public void run() {
11697                // 5 second sleep to let stacks arrive and be batched together
11698                try {
11699                    Thread.sleep(5000);  // 5 seconds
11700                } catch (InterruptedException e) {}
11701
11702                String errorReport;
11703                synchronized (mStrictModeBuffer) {
11704                    errorReport = mStrictModeBuffer.toString();
11705                    if (errorReport.length() == 0) {
11706                        return;
11707                    }
11708                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11709                    mStrictModeBuffer.trimToSize();
11710                }
11711                dbox.addText(dropboxTag, errorReport);
11712            }
11713        }.start();
11714    }
11715
11716    /**
11717     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11718     * @param app object of the crashing app, null for the system server
11719     * @param tag reported by the caller
11720     * @param system whether this wtf is coming from the system
11721     * @param crashInfo describing the context of the error
11722     * @return true if the process should exit immediately (WTF is fatal)
11723     */
11724    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11725            final ApplicationErrorReport.CrashInfo crashInfo) {
11726        final int callingUid = Binder.getCallingUid();
11727        final int callingPid = Binder.getCallingPid();
11728
11729        if (system) {
11730            // If this is coming from the system, we could very well have low-level
11731            // system locks held, so we want to do this all asynchronously.  And we
11732            // never want this to become fatal, so there is that too.
11733            mHandler.post(new Runnable() {
11734                @Override public void run() {
11735                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11736                }
11737            });
11738            return false;
11739        }
11740
11741        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11742                crashInfo);
11743
11744        if (r != null && r.pid != Process.myPid() &&
11745                Settings.Global.getInt(mContext.getContentResolver(),
11746                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11747            crashApplication(r, crashInfo);
11748            return true;
11749        } else {
11750            return false;
11751        }
11752    }
11753
11754    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11755            final ApplicationErrorReport.CrashInfo crashInfo) {
11756        final ProcessRecord r = findAppProcess(app, "WTF");
11757        final String processName = app == null ? "system_server"
11758                : (r == null ? "unknown" : r.processName);
11759
11760        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11761                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11762
11763        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11764
11765        return r;
11766    }
11767
11768    /**
11769     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11770     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11771     */
11772    private ProcessRecord findAppProcess(IBinder app, String reason) {
11773        if (app == null) {
11774            return null;
11775        }
11776
11777        synchronized (this) {
11778            final int NP = mProcessNames.getMap().size();
11779            for (int ip=0; ip<NP; ip++) {
11780                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11781                final int NA = apps.size();
11782                for (int ia=0; ia<NA; ia++) {
11783                    ProcessRecord p = apps.valueAt(ia);
11784                    if (p.thread != null && p.thread.asBinder() == app) {
11785                        return p;
11786                    }
11787                }
11788            }
11789
11790            Slog.w(TAG, "Can't find mystery application for " + reason
11791                    + " from pid=" + Binder.getCallingPid()
11792                    + " uid=" + Binder.getCallingUid() + ": " + app);
11793            return null;
11794        }
11795    }
11796
11797    /**
11798     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11799     * to append various headers to the dropbox log text.
11800     */
11801    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11802            StringBuilder sb) {
11803        // Watchdog thread ends up invoking this function (with
11804        // a null ProcessRecord) to add the stack file to dropbox.
11805        // Do not acquire a lock on this (am) in such cases, as it
11806        // could cause a potential deadlock, if and when watchdog
11807        // is invoked due to unavailability of lock on am and it
11808        // would prevent watchdog from killing system_server.
11809        if (process == null) {
11810            sb.append("Process: ").append(processName).append("\n");
11811            return;
11812        }
11813        // Note: ProcessRecord 'process' is guarded by the service
11814        // instance.  (notably process.pkgList, which could otherwise change
11815        // concurrently during execution of this method)
11816        synchronized (this) {
11817            sb.append("Process: ").append(processName).append("\n");
11818            int flags = process.info.flags;
11819            IPackageManager pm = AppGlobals.getPackageManager();
11820            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11821            for (int ip=0; ip<process.pkgList.size(); ip++) {
11822                String pkg = process.pkgList.keyAt(ip);
11823                sb.append("Package: ").append(pkg);
11824                try {
11825                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11826                    if (pi != null) {
11827                        sb.append(" v").append(pi.versionCode);
11828                        if (pi.versionName != null) {
11829                            sb.append(" (").append(pi.versionName).append(")");
11830                        }
11831                    }
11832                } catch (RemoteException e) {
11833                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11834                }
11835                sb.append("\n");
11836            }
11837        }
11838    }
11839
11840    private static String processClass(ProcessRecord process) {
11841        if (process == null || process.pid == MY_PID) {
11842            return "system_server";
11843        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11844            return "system_app";
11845        } else {
11846            return "data_app";
11847        }
11848    }
11849
11850    /**
11851     * Write a description of an error (crash, WTF, ANR) to the drop box.
11852     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11853     * @param process which caused the error, null means the system server
11854     * @param activity which triggered the error, null if unknown
11855     * @param parent activity related to the error, null if unknown
11856     * @param subject line related to the error, null if absent
11857     * @param report in long form describing the error, null if absent
11858     * @param logFile to include in the report, null if none
11859     * @param crashInfo giving an application stack trace, null if absent
11860     */
11861    public void addErrorToDropBox(String eventType,
11862            ProcessRecord process, String processName, ActivityRecord activity,
11863            ActivityRecord parent, String subject,
11864            final String report, final File logFile,
11865            final ApplicationErrorReport.CrashInfo crashInfo) {
11866        // NOTE -- this must never acquire the ActivityManagerService lock,
11867        // otherwise the watchdog may be prevented from resetting the system.
11868
11869        final String dropboxTag = processClass(process) + "_" + eventType;
11870        final DropBoxManager dbox = (DropBoxManager)
11871                mContext.getSystemService(Context.DROPBOX_SERVICE);
11872
11873        // Exit early if the dropbox isn't configured to accept this report type.
11874        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11875
11876        final StringBuilder sb = new StringBuilder(1024);
11877        appendDropBoxProcessHeaders(process, processName, sb);
11878        if (activity != null) {
11879            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11880        }
11881        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11882            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11883        }
11884        if (parent != null && parent != activity) {
11885            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11886        }
11887        if (subject != null) {
11888            sb.append("Subject: ").append(subject).append("\n");
11889        }
11890        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11891        if (Debug.isDebuggerConnected()) {
11892            sb.append("Debugger: Connected\n");
11893        }
11894        sb.append("\n");
11895
11896        // Do the rest in a worker thread to avoid blocking the caller on I/O
11897        // (After this point, we shouldn't access AMS internal data structures.)
11898        Thread worker = new Thread("Error dump: " + dropboxTag) {
11899            @Override
11900            public void run() {
11901                if (report != null) {
11902                    sb.append(report);
11903                }
11904                if (logFile != null) {
11905                    try {
11906                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11907                                    "\n\n[[TRUNCATED]]"));
11908                    } catch (IOException e) {
11909                        Slog.e(TAG, "Error reading " + logFile, e);
11910                    }
11911                }
11912                if (crashInfo != null && crashInfo.stackTrace != null) {
11913                    sb.append(crashInfo.stackTrace);
11914                }
11915
11916                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11917                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11918                if (lines > 0) {
11919                    sb.append("\n");
11920
11921                    // Merge several logcat streams, and take the last N lines
11922                    InputStreamReader input = null;
11923                    try {
11924                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11925                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11926                                "-b", "crash",
11927                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11928
11929                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11930                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11931                        input = new InputStreamReader(logcat.getInputStream());
11932
11933                        int num;
11934                        char[] buf = new char[8192];
11935                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11936                    } catch (IOException e) {
11937                        Slog.e(TAG, "Error running logcat", e);
11938                    } finally {
11939                        if (input != null) try { input.close(); } catch (IOException e) {}
11940                    }
11941                }
11942
11943                dbox.addText(dropboxTag, sb.toString());
11944            }
11945        };
11946
11947        if (process == null) {
11948            // If process is null, we are being called from some internal code
11949            // and may be about to die -- run this synchronously.
11950            worker.run();
11951        } else {
11952            worker.start();
11953        }
11954    }
11955
11956    /**
11957     * Bring up the "unexpected error" dialog box for a crashing app.
11958     * Deal with edge cases (intercepts from instrumented applications,
11959     * ActivityController, error intent receivers, that sort of thing).
11960     * @param r the application crashing
11961     * @param crashInfo describing the failure
11962     */
11963    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11964        long timeMillis = System.currentTimeMillis();
11965        String shortMsg = crashInfo.exceptionClassName;
11966        String longMsg = crashInfo.exceptionMessage;
11967        String stackTrace = crashInfo.stackTrace;
11968        if (shortMsg != null && longMsg != null) {
11969            longMsg = shortMsg + ": " + longMsg;
11970        } else if (shortMsg != null) {
11971            longMsg = shortMsg;
11972        }
11973
11974        AppErrorResult result = new AppErrorResult();
11975        synchronized (this) {
11976            if (mController != null) {
11977                try {
11978                    String name = r != null ? r.processName : null;
11979                    int pid = r != null ? r.pid : Binder.getCallingPid();
11980                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11981                    if (!mController.appCrashed(name, pid,
11982                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11983                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11984                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11985                            Slog.w(TAG, "Skip killing native crashed app " + name
11986                                    + "(" + pid + ") during testing");
11987                        } else {
11988                            Slog.w(TAG, "Force-killing crashed app " + name
11989                                    + " at watcher's request");
11990                            if (r != null) {
11991                                r.kill("crash", true);
11992                            } else {
11993                                // Huh.
11994                                Process.killProcess(pid);
11995                                Process.killProcessGroup(uid, pid);
11996                            }
11997                        }
11998                        return;
11999                    }
12000                } catch (RemoteException e) {
12001                    mController = null;
12002                    Watchdog.getInstance().setActivityController(null);
12003                }
12004            }
12005
12006            final long origId = Binder.clearCallingIdentity();
12007
12008            // If this process is running instrumentation, finish it.
12009            if (r != null && r.instrumentationClass != null) {
12010                Slog.w(TAG, "Error in app " + r.processName
12011                      + " running instrumentation " + r.instrumentationClass + ":");
12012                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12013                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12014                Bundle info = new Bundle();
12015                info.putString("shortMsg", shortMsg);
12016                info.putString("longMsg", longMsg);
12017                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12018                Binder.restoreCallingIdentity(origId);
12019                return;
12020            }
12021
12022            // If we can't identify the process or it's already exceeded its crash quota,
12023            // quit right away without showing a crash dialog.
12024            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12025                Binder.restoreCallingIdentity(origId);
12026                return;
12027            }
12028
12029            Message msg = Message.obtain();
12030            msg.what = SHOW_ERROR_MSG;
12031            HashMap data = new HashMap();
12032            data.put("result", result);
12033            data.put("app", r);
12034            msg.obj = data;
12035            mHandler.sendMessage(msg);
12036
12037            Binder.restoreCallingIdentity(origId);
12038        }
12039
12040        int res = result.get();
12041
12042        Intent appErrorIntent = null;
12043        synchronized (this) {
12044            if (r != null && !r.isolated) {
12045                // XXX Can't keep track of crash time for isolated processes,
12046                // since they don't have a persistent identity.
12047                mProcessCrashTimes.put(r.info.processName, r.uid,
12048                        SystemClock.uptimeMillis());
12049            }
12050            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12051                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12052            }
12053        }
12054
12055        if (appErrorIntent != null) {
12056            try {
12057                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12058            } catch (ActivityNotFoundException e) {
12059                Slog.w(TAG, "bug report receiver dissappeared", e);
12060            }
12061        }
12062    }
12063
12064    Intent createAppErrorIntentLocked(ProcessRecord r,
12065            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12066        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12067        if (report == null) {
12068            return null;
12069        }
12070        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12071        result.setComponent(r.errorReportReceiver);
12072        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12073        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12074        return result;
12075    }
12076
12077    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12078            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12079        if (r.errorReportReceiver == null) {
12080            return null;
12081        }
12082
12083        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12084            return null;
12085        }
12086
12087        ApplicationErrorReport report = new ApplicationErrorReport();
12088        report.packageName = r.info.packageName;
12089        report.installerPackageName = r.errorReportReceiver.getPackageName();
12090        report.processName = r.processName;
12091        report.time = timeMillis;
12092        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12093
12094        if (r.crashing || r.forceCrashReport) {
12095            report.type = ApplicationErrorReport.TYPE_CRASH;
12096            report.crashInfo = crashInfo;
12097        } else if (r.notResponding) {
12098            report.type = ApplicationErrorReport.TYPE_ANR;
12099            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12100
12101            report.anrInfo.activity = r.notRespondingReport.tag;
12102            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12103            report.anrInfo.info = r.notRespondingReport.longMsg;
12104        }
12105
12106        return report;
12107    }
12108
12109    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12110        enforceNotIsolatedCaller("getProcessesInErrorState");
12111        // assume our apps are happy - lazy create the list
12112        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12113
12114        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12115                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12116        int userId = UserHandle.getUserId(Binder.getCallingUid());
12117
12118        synchronized (this) {
12119
12120            // iterate across all processes
12121            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12122                ProcessRecord app = mLruProcesses.get(i);
12123                if (!allUsers && app.userId != userId) {
12124                    continue;
12125                }
12126                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12127                    // This one's in trouble, so we'll generate a report for it
12128                    // crashes are higher priority (in case there's a crash *and* an anr)
12129                    ActivityManager.ProcessErrorStateInfo report = null;
12130                    if (app.crashing) {
12131                        report = app.crashingReport;
12132                    } else if (app.notResponding) {
12133                        report = app.notRespondingReport;
12134                    }
12135
12136                    if (report != null) {
12137                        if (errList == null) {
12138                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12139                        }
12140                        errList.add(report);
12141                    } else {
12142                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12143                                " crashing = " + app.crashing +
12144                                " notResponding = " + app.notResponding);
12145                    }
12146                }
12147            }
12148        }
12149
12150        return errList;
12151    }
12152
12153    static int procStateToImportance(int procState, int memAdj,
12154            ActivityManager.RunningAppProcessInfo currApp) {
12155        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12156        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12157            currApp.lru = memAdj;
12158        } else {
12159            currApp.lru = 0;
12160        }
12161        return imp;
12162    }
12163
12164    private void fillInProcMemInfo(ProcessRecord app,
12165            ActivityManager.RunningAppProcessInfo outInfo) {
12166        outInfo.pid = app.pid;
12167        outInfo.uid = app.info.uid;
12168        if (mHeavyWeightProcess == app) {
12169            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12170        }
12171        if (app.persistent) {
12172            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12173        }
12174        if (app.activities.size() > 0) {
12175            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12176        }
12177        outInfo.lastTrimLevel = app.trimMemoryLevel;
12178        int adj = app.curAdj;
12179        int procState = app.curProcState;
12180        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12181        outInfo.importanceReasonCode = app.adjTypeCode;
12182        outInfo.processState = app.curProcState;
12183    }
12184
12185    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12186        enforceNotIsolatedCaller("getRunningAppProcesses");
12187        // Lazy instantiation of list
12188        List<ActivityManager.RunningAppProcessInfo> runList = null;
12189        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12190                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12191        int userId = UserHandle.getUserId(Binder.getCallingUid());
12192        synchronized (this) {
12193            // Iterate across all processes
12194            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12195                ProcessRecord app = mLruProcesses.get(i);
12196                if (!allUsers && app.userId != userId) {
12197                    continue;
12198                }
12199                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12200                    // Generate process state info for running application
12201                    ActivityManager.RunningAppProcessInfo currApp =
12202                        new ActivityManager.RunningAppProcessInfo(app.processName,
12203                                app.pid, app.getPackageList());
12204                    fillInProcMemInfo(app, currApp);
12205                    if (app.adjSource instanceof ProcessRecord) {
12206                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12207                        currApp.importanceReasonImportance =
12208                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12209                                        app.adjSourceProcState);
12210                    } else if (app.adjSource instanceof ActivityRecord) {
12211                        ActivityRecord r = (ActivityRecord)app.adjSource;
12212                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12213                    }
12214                    if (app.adjTarget instanceof ComponentName) {
12215                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12216                    }
12217                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12218                    //        + " lru=" + currApp.lru);
12219                    if (runList == null) {
12220                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12221                    }
12222                    runList.add(currApp);
12223                }
12224            }
12225        }
12226        return runList;
12227    }
12228
12229    public List<ApplicationInfo> getRunningExternalApplications() {
12230        enforceNotIsolatedCaller("getRunningExternalApplications");
12231        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12232        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12233        if (runningApps != null && runningApps.size() > 0) {
12234            Set<String> extList = new HashSet<String>();
12235            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12236                if (app.pkgList != null) {
12237                    for (String pkg : app.pkgList) {
12238                        extList.add(pkg);
12239                    }
12240                }
12241            }
12242            IPackageManager pm = AppGlobals.getPackageManager();
12243            for (String pkg : extList) {
12244                try {
12245                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12246                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12247                        retList.add(info);
12248                    }
12249                } catch (RemoteException e) {
12250                }
12251            }
12252        }
12253        return retList;
12254    }
12255
12256    @Override
12257    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12258        enforceNotIsolatedCaller("getMyMemoryState");
12259        synchronized (this) {
12260            ProcessRecord proc;
12261            synchronized (mPidsSelfLocked) {
12262                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12263            }
12264            fillInProcMemInfo(proc, outInfo);
12265        }
12266    }
12267
12268    @Override
12269    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12270        if (checkCallingPermission(android.Manifest.permission.DUMP)
12271                != PackageManager.PERMISSION_GRANTED) {
12272            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12273                    + Binder.getCallingPid()
12274                    + ", uid=" + Binder.getCallingUid()
12275                    + " without permission "
12276                    + android.Manifest.permission.DUMP);
12277            return;
12278        }
12279
12280        boolean dumpAll = false;
12281        boolean dumpClient = false;
12282        String dumpPackage = null;
12283
12284        int opti = 0;
12285        while (opti < args.length) {
12286            String opt = args[opti];
12287            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12288                break;
12289            }
12290            opti++;
12291            if ("-a".equals(opt)) {
12292                dumpAll = true;
12293            } else if ("-c".equals(opt)) {
12294                dumpClient = true;
12295            } else if ("-h".equals(opt)) {
12296                pw.println("Activity manager dump options:");
12297                pw.println("  [-a] [-c] [-h] [cmd] ...");
12298                pw.println("  cmd may be one of:");
12299                pw.println("    a[ctivities]: activity stack state");
12300                pw.println("    r[recents]: recent activities state");
12301                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12302                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12303                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12304                pw.println("    o[om]: out of memory management");
12305                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12306                pw.println("    provider [COMP_SPEC]: provider client-side state");
12307                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12308                pw.println("    service [COMP_SPEC]: service client-side state");
12309                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12310                pw.println("    all: dump all activities");
12311                pw.println("    top: dump the top activity");
12312                pw.println("    write: write all pending state to storage");
12313                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12314                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12315                pw.println("    a partial substring in a component name, a");
12316                pw.println("    hex object identifier.");
12317                pw.println("  -a: include all available server state.");
12318                pw.println("  -c: include client state.");
12319                return;
12320            } else {
12321                pw.println("Unknown argument: " + opt + "; use -h for help");
12322            }
12323        }
12324
12325        long origId = Binder.clearCallingIdentity();
12326        boolean more = false;
12327        // Is the caller requesting to dump a particular piece of data?
12328        if (opti < args.length) {
12329            String cmd = args[opti];
12330            opti++;
12331            if ("activities".equals(cmd) || "a".equals(cmd)) {
12332                synchronized (this) {
12333                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12334                }
12335            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12336                synchronized (this) {
12337                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12338                }
12339            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12340                String[] newArgs;
12341                String name;
12342                if (opti >= args.length) {
12343                    name = null;
12344                    newArgs = EMPTY_STRING_ARRAY;
12345                } else {
12346                    name = args[opti];
12347                    opti++;
12348                    newArgs = new String[args.length - opti];
12349                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12350                            args.length - opti);
12351                }
12352                synchronized (this) {
12353                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12354                }
12355            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12356                String[] newArgs;
12357                String name;
12358                if (opti >= args.length) {
12359                    name = null;
12360                    newArgs = EMPTY_STRING_ARRAY;
12361                } else {
12362                    name = args[opti];
12363                    opti++;
12364                    newArgs = new String[args.length - opti];
12365                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12366                            args.length - opti);
12367                }
12368                synchronized (this) {
12369                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12370                }
12371            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12372                String[] newArgs;
12373                String name;
12374                if (opti >= args.length) {
12375                    name = null;
12376                    newArgs = EMPTY_STRING_ARRAY;
12377                } else {
12378                    name = args[opti];
12379                    opti++;
12380                    newArgs = new String[args.length - opti];
12381                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12382                            args.length - opti);
12383                }
12384                synchronized (this) {
12385                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12386                }
12387            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12388                synchronized (this) {
12389                    dumpOomLocked(fd, pw, args, opti, true);
12390                }
12391            } else if ("provider".equals(cmd)) {
12392                String[] newArgs;
12393                String name;
12394                if (opti >= args.length) {
12395                    name = null;
12396                    newArgs = EMPTY_STRING_ARRAY;
12397                } else {
12398                    name = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12402                }
12403                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12404                    pw.println("No providers match: " + name);
12405                    pw.println("Use -h for help.");
12406                }
12407            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12408                synchronized (this) {
12409                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12410                }
12411            } else if ("service".equals(cmd)) {
12412                String[] newArgs;
12413                String name;
12414                if (opti >= args.length) {
12415                    name = null;
12416                    newArgs = EMPTY_STRING_ARRAY;
12417                } else {
12418                    name = args[opti];
12419                    opti++;
12420                    newArgs = new String[args.length - opti];
12421                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12422                            args.length - opti);
12423                }
12424                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12425                    pw.println("No services match: " + name);
12426                    pw.println("Use -h for help.");
12427                }
12428            } else if ("package".equals(cmd)) {
12429                String[] newArgs;
12430                if (opti >= args.length) {
12431                    pw.println("package: no package name specified");
12432                    pw.println("Use -h for help.");
12433                } else {
12434                    dumpPackage = args[opti];
12435                    opti++;
12436                    newArgs = new String[args.length - opti];
12437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12438                            args.length - opti);
12439                    args = newArgs;
12440                    opti = 0;
12441                    more = true;
12442                }
12443            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12444                synchronized (this) {
12445                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12446                }
12447            } else if ("write".equals(cmd)) {
12448                mTaskPersister.flush();
12449                pw.println("All tasks persisted.");
12450                return;
12451            } else {
12452                // Dumping a single activity?
12453                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12454                    pw.println("Bad activity command, or no activities match: " + cmd);
12455                    pw.println("Use -h for help.");
12456                }
12457            }
12458            if (!more) {
12459                Binder.restoreCallingIdentity(origId);
12460                return;
12461            }
12462        }
12463
12464        // No piece of data specified, dump everything.
12465        synchronized (this) {
12466            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12467            pw.println();
12468            if (dumpAll) {
12469                pw.println("-------------------------------------------------------------------------------");
12470            }
12471            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12472            pw.println();
12473            if (dumpAll) {
12474                pw.println("-------------------------------------------------------------------------------");
12475            }
12476            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12477            pw.println();
12478            if (dumpAll) {
12479                pw.println("-------------------------------------------------------------------------------");
12480            }
12481            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12482            pw.println();
12483            if (dumpAll) {
12484                pw.println("-------------------------------------------------------------------------------");
12485            }
12486            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12487            pw.println();
12488            if (dumpAll) {
12489                pw.println("-------------------------------------------------------------------------------");
12490            }
12491            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12492            pw.println();
12493            if (dumpAll) {
12494                pw.println("-------------------------------------------------------------------------------");
12495            }
12496            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12497        }
12498        Binder.restoreCallingIdentity(origId);
12499    }
12500
12501    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12502            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12503        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12504
12505        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12506                dumpPackage);
12507        boolean needSep = printedAnything;
12508
12509        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12510                dumpPackage, needSep, "  mFocusedActivity: ");
12511        if (printed) {
12512            printedAnything = true;
12513            needSep = false;
12514        }
12515
12516        if (dumpPackage == null) {
12517            if (needSep) {
12518                pw.println();
12519            }
12520            needSep = true;
12521            printedAnything = true;
12522            mStackSupervisor.dump(pw, "  ");
12523        }
12524
12525        if (!printedAnything) {
12526            pw.println("  (nothing)");
12527        }
12528    }
12529
12530    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12531            int opti, boolean dumpAll, String dumpPackage) {
12532        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12533
12534        boolean printedAnything = false;
12535
12536        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12537            boolean printedHeader = false;
12538
12539            final int N = mRecentTasks.size();
12540            for (int i=0; i<N; i++) {
12541                TaskRecord tr = mRecentTasks.get(i);
12542                if (dumpPackage != null) {
12543                    if (tr.realActivity == null ||
12544                            !dumpPackage.equals(tr.realActivity)) {
12545                        continue;
12546                    }
12547                }
12548                if (!printedHeader) {
12549                    pw.println("  Recent tasks:");
12550                    printedHeader = true;
12551                    printedAnything = true;
12552                }
12553                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12554                        pw.println(tr);
12555                if (dumpAll) {
12556                    mRecentTasks.get(i).dump(pw, "    ");
12557                }
12558            }
12559        }
12560
12561        if (!printedAnything) {
12562            pw.println("  (nothing)");
12563        }
12564    }
12565
12566    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12567            int opti, boolean dumpAll, String dumpPackage) {
12568        boolean needSep = false;
12569        boolean printedAnything = false;
12570        int numPers = 0;
12571
12572        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12573
12574        if (dumpAll) {
12575            final int NP = mProcessNames.getMap().size();
12576            for (int ip=0; ip<NP; ip++) {
12577                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12578                final int NA = procs.size();
12579                for (int ia=0; ia<NA; ia++) {
12580                    ProcessRecord r = procs.valueAt(ia);
12581                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12582                        continue;
12583                    }
12584                    if (!needSep) {
12585                        pw.println("  All known processes:");
12586                        needSep = true;
12587                        printedAnything = true;
12588                    }
12589                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12590                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12591                        pw.print(" "); pw.println(r);
12592                    r.dump(pw, "    ");
12593                    if (r.persistent) {
12594                        numPers++;
12595                    }
12596                }
12597            }
12598        }
12599
12600        if (mIsolatedProcesses.size() > 0) {
12601            boolean printed = false;
12602            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12603                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12604                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12605                    continue;
12606                }
12607                if (!printed) {
12608                    if (needSep) {
12609                        pw.println();
12610                    }
12611                    pw.println("  Isolated process list (sorted by uid):");
12612                    printedAnything = true;
12613                    printed = true;
12614                    needSep = true;
12615                }
12616                pw.println(String.format("%sIsolated #%2d: %s",
12617                        "    ", i, r.toString()));
12618            }
12619        }
12620
12621        if (mLruProcesses.size() > 0) {
12622            if (needSep) {
12623                pw.println();
12624            }
12625            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12626                    pw.print(" total, non-act at ");
12627                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12628                    pw.print(", non-svc at ");
12629                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12630                    pw.println("):");
12631            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12632            needSep = true;
12633            printedAnything = true;
12634        }
12635
12636        if (dumpAll || dumpPackage != null) {
12637            synchronized (mPidsSelfLocked) {
12638                boolean printed = false;
12639                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12640                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12641                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12642                        continue;
12643                    }
12644                    if (!printed) {
12645                        if (needSep) pw.println();
12646                        needSep = true;
12647                        pw.println("  PID mappings:");
12648                        printed = true;
12649                        printedAnything = true;
12650                    }
12651                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12652                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12653                }
12654            }
12655        }
12656
12657        if (mForegroundProcesses.size() > 0) {
12658            synchronized (mPidsSelfLocked) {
12659                boolean printed = false;
12660                for (int i=0; i<mForegroundProcesses.size(); i++) {
12661                    ProcessRecord r = mPidsSelfLocked.get(
12662                            mForegroundProcesses.valueAt(i).pid);
12663                    if (dumpPackage != null && (r == null
12664                            || !r.pkgList.containsKey(dumpPackage))) {
12665                        continue;
12666                    }
12667                    if (!printed) {
12668                        if (needSep) pw.println();
12669                        needSep = true;
12670                        pw.println("  Foreground Processes:");
12671                        printed = true;
12672                        printedAnything = true;
12673                    }
12674                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12675                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12676                }
12677            }
12678        }
12679
12680        if (mPersistentStartingProcesses.size() > 0) {
12681            if (needSep) pw.println();
12682            needSep = true;
12683            printedAnything = true;
12684            pw.println("  Persisent processes that are starting:");
12685            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12686                    "Starting Norm", "Restarting PERS", dumpPackage);
12687        }
12688
12689        if (mRemovedProcesses.size() > 0) {
12690            if (needSep) pw.println();
12691            needSep = true;
12692            printedAnything = true;
12693            pw.println("  Processes that are being removed:");
12694            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12695                    "Removed Norm", "Removed PERS", dumpPackage);
12696        }
12697
12698        if (mProcessesOnHold.size() > 0) {
12699            if (needSep) pw.println();
12700            needSep = true;
12701            printedAnything = true;
12702            pw.println("  Processes that are on old until the system is ready:");
12703            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12704                    "OnHold Norm", "OnHold PERS", dumpPackage);
12705        }
12706
12707        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12708
12709        if (mProcessCrashTimes.getMap().size() > 0) {
12710            boolean printed = false;
12711            long now = SystemClock.uptimeMillis();
12712            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12713            final int NP = pmap.size();
12714            for (int ip=0; ip<NP; ip++) {
12715                String pname = pmap.keyAt(ip);
12716                SparseArray<Long> uids = pmap.valueAt(ip);
12717                final int N = uids.size();
12718                for (int i=0; i<N; i++) {
12719                    int puid = uids.keyAt(i);
12720                    ProcessRecord r = mProcessNames.get(pname, puid);
12721                    if (dumpPackage != null && (r == null
12722                            || !r.pkgList.containsKey(dumpPackage))) {
12723                        continue;
12724                    }
12725                    if (!printed) {
12726                        if (needSep) pw.println();
12727                        needSep = true;
12728                        pw.println("  Time since processes crashed:");
12729                        printed = true;
12730                        printedAnything = true;
12731                    }
12732                    pw.print("    Process "); pw.print(pname);
12733                            pw.print(" uid "); pw.print(puid);
12734                            pw.print(": last crashed ");
12735                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12736                            pw.println(" ago");
12737                }
12738            }
12739        }
12740
12741        if (mBadProcesses.getMap().size() > 0) {
12742            boolean printed = false;
12743            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12744            final int NP = pmap.size();
12745            for (int ip=0; ip<NP; ip++) {
12746                String pname = pmap.keyAt(ip);
12747                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12748                final int N = uids.size();
12749                for (int i=0; i<N; i++) {
12750                    int puid = uids.keyAt(i);
12751                    ProcessRecord r = mProcessNames.get(pname, puid);
12752                    if (dumpPackage != null && (r == null
12753                            || !r.pkgList.containsKey(dumpPackage))) {
12754                        continue;
12755                    }
12756                    if (!printed) {
12757                        if (needSep) pw.println();
12758                        needSep = true;
12759                        pw.println("  Bad processes:");
12760                        printedAnything = true;
12761                    }
12762                    BadProcessInfo info = uids.valueAt(i);
12763                    pw.print("    Bad process "); pw.print(pname);
12764                            pw.print(" uid "); pw.print(puid);
12765                            pw.print(": crashed at time "); pw.println(info.time);
12766                    if (info.shortMsg != null) {
12767                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12768                    }
12769                    if (info.longMsg != null) {
12770                        pw.print("      Long msg: "); pw.println(info.longMsg);
12771                    }
12772                    if (info.stack != null) {
12773                        pw.println("      Stack:");
12774                        int lastPos = 0;
12775                        for (int pos=0; pos<info.stack.length(); pos++) {
12776                            if (info.stack.charAt(pos) == '\n') {
12777                                pw.print("        ");
12778                                pw.write(info.stack, lastPos, pos-lastPos);
12779                                pw.println();
12780                                lastPos = pos+1;
12781                            }
12782                        }
12783                        if (lastPos < info.stack.length()) {
12784                            pw.print("        ");
12785                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12786                            pw.println();
12787                        }
12788                    }
12789                }
12790            }
12791        }
12792
12793        if (dumpPackage == null) {
12794            pw.println();
12795            needSep = false;
12796            pw.println("  mStartedUsers:");
12797            for (int i=0; i<mStartedUsers.size(); i++) {
12798                UserStartedState uss = mStartedUsers.valueAt(i);
12799                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12800                        pw.print(": "); uss.dump("", pw);
12801            }
12802            pw.print("  mStartedUserArray: [");
12803            for (int i=0; i<mStartedUserArray.length; i++) {
12804                if (i > 0) pw.print(", ");
12805                pw.print(mStartedUserArray[i]);
12806            }
12807            pw.println("]");
12808            pw.print("  mUserLru: [");
12809            for (int i=0; i<mUserLru.size(); i++) {
12810                if (i > 0) pw.print(", ");
12811                pw.print(mUserLru.get(i));
12812            }
12813            pw.println("]");
12814            if (dumpAll) {
12815                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12816            }
12817            synchronized (mUserProfileGroupIdsSelfLocked) {
12818                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12819                    pw.println("  mUserProfileGroupIds:");
12820                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12821                        pw.print("    User #");
12822                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12823                        pw.print(" -> profile #");
12824                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12825                    }
12826                }
12827            }
12828        }
12829        if (mHomeProcess != null && (dumpPackage == null
12830                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12831            if (needSep) {
12832                pw.println();
12833                needSep = false;
12834            }
12835            pw.println("  mHomeProcess: " + mHomeProcess);
12836        }
12837        if (mPreviousProcess != null && (dumpPackage == null
12838                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12839            if (needSep) {
12840                pw.println();
12841                needSep = false;
12842            }
12843            pw.println("  mPreviousProcess: " + mPreviousProcess);
12844        }
12845        if (dumpAll) {
12846            StringBuilder sb = new StringBuilder(128);
12847            sb.append("  mPreviousProcessVisibleTime: ");
12848            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12849            pw.println(sb);
12850        }
12851        if (mHeavyWeightProcess != null && (dumpPackage == null
12852                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12853            if (needSep) {
12854                pw.println();
12855                needSep = false;
12856            }
12857            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12858        }
12859        if (dumpPackage == null) {
12860            pw.println("  mConfiguration: " + mConfiguration);
12861        }
12862        if (dumpAll) {
12863            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12864            if (mCompatModePackages.getPackages().size() > 0) {
12865                boolean printed = false;
12866                for (Map.Entry<String, Integer> entry
12867                        : mCompatModePackages.getPackages().entrySet()) {
12868                    String pkg = entry.getKey();
12869                    int mode = entry.getValue();
12870                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12871                        continue;
12872                    }
12873                    if (!printed) {
12874                        pw.println("  mScreenCompatPackages:");
12875                        printed = true;
12876                    }
12877                    pw.print("    "); pw.print(pkg); pw.print(": ");
12878                            pw.print(mode); pw.println();
12879                }
12880            }
12881        }
12882        if (dumpPackage == null) {
12883            pw.println("  mWakefulness="
12884                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12885            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12886                    + lockScreenShownToString());
12887            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12888        }
12889        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12890                || mOrigWaitForDebugger) {
12891            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12892                    || dumpPackage.equals(mOrigDebugApp)) {
12893                if (needSep) {
12894                    pw.println();
12895                    needSep = false;
12896                }
12897                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12898                        + " mDebugTransient=" + mDebugTransient
12899                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12900            }
12901        }
12902        if (mOpenGlTraceApp != null) {
12903            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12904                if (needSep) {
12905                    pw.println();
12906                    needSep = false;
12907                }
12908                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12909            }
12910        }
12911        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12912                || mProfileFd != null) {
12913            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12914                if (needSep) {
12915                    pw.println();
12916                    needSep = false;
12917                }
12918                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12919                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12920                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12921                        + mAutoStopProfiler);
12922                pw.println("  mProfileType=" + mProfileType);
12923            }
12924        }
12925        if (dumpPackage == null) {
12926            if (mAlwaysFinishActivities || mController != null) {
12927                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12928                        + " mController=" + mController);
12929            }
12930            if (dumpAll) {
12931                pw.println("  Total persistent processes: " + numPers);
12932                pw.println("  mProcessesReady=" + mProcessesReady
12933                        + " mSystemReady=" + mSystemReady
12934                        + " mBooted=" + mBooted
12935                        + " mFactoryTest=" + mFactoryTest);
12936                pw.println("  mBooting=" + mBooting
12937                        + " mCallFinishBooting=" + mCallFinishBooting
12938                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12939                pw.print("  mLastPowerCheckRealtime=");
12940                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12941                        pw.println("");
12942                pw.print("  mLastPowerCheckUptime=");
12943                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12944                        pw.println("");
12945                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12946                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12947                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12948                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12949                        + " (" + mLruProcesses.size() + " total)"
12950                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12951                        + " mNumServiceProcs=" + mNumServiceProcs
12952                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12953                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12954                        + " mLastMemoryLevel" + mLastMemoryLevel
12955                        + " mLastNumProcesses" + mLastNumProcesses);
12956                long now = SystemClock.uptimeMillis();
12957                pw.print("  mLastIdleTime=");
12958                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12959                        pw.print(" mLowRamSinceLastIdle=");
12960                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12961                        pw.println();
12962            }
12963        }
12964
12965        if (!printedAnything) {
12966            pw.println("  (nothing)");
12967        }
12968    }
12969
12970    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12971            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12972        if (mProcessesToGc.size() > 0) {
12973            boolean printed = false;
12974            long now = SystemClock.uptimeMillis();
12975            for (int i=0; i<mProcessesToGc.size(); i++) {
12976                ProcessRecord proc = mProcessesToGc.get(i);
12977                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12978                    continue;
12979                }
12980                if (!printed) {
12981                    if (needSep) pw.println();
12982                    needSep = true;
12983                    pw.println("  Processes that are waiting to GC:");
12984                    printed = true;
12985                }
12986                pw.print("    Process "); pw.println(proc);
12987                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12988                        pw.print(", last gced=");
12989                        pw.print(now-proc.lastRequestedGc);
12990                        pw.print(" ms ago, last lowMem=");
12991                        pw.print(now-proc.lastLowMemory);
12992                        pw.println(" ms ago");
12993
12994            }
12995        }
12996        return needSep;
12997    }
12998
12999    void printOomLevel(PrintWriter pw, String name, int adj) {
13000        pw.print("    ");
13001        if (adj >= 0) {
13002            pw.print(' ');
13003            if (adj < 10) pw.print(' ');
13004        } else {
13005            if (adj > -10) pw.print(' ');
13006        }
13007        pw.print(adj);
13008        pw.print(": ");
13009        pw.print(name);
13010        pw.print(" (");
13011        pw.print(mProcessList.getMemLevel(adj)/1024);
13012        pw.println(" kB)");
13013    }
13014
13015    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13016            int opti, boolean dumpAll) {
13017        boolean needSep = false;
13018
13019        if (mLruProcesses.size() > 0) {
13020            if (needSep) pw.println();
13021            needSep = true;
13022            pw.println("  OOM levels:");
13023            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13024            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13025            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13026            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13027            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13028            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13029            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13030            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13031            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13032            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13033            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13034            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13035            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13036            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13037
13038            if (needSep) pw.println();
13039            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13040                    pw.print(" total, non-act at ");
13041                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13042                    pw.print(", non-svc at ");
13043                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13044                    pw.println("):");
13045            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13046            needSep = true;
13047        }
13048
13049        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13050
13051        pw.println();
13052        pw.println("  mHomeProcess: " + mHomeProcess);
13053        pw.println("  mPreviousProcess: " + mPreviousProcess);
13054        if (mHeavyWeightProcess != null) {
13055            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13056        }
13057
13058        return true;
13059    }
13060
13061    /**
13062     * There are three ways to call this:
13063     *  - no provider specified: dump all the providers
13064     *  - a flattened component name that matched an existing provider was specified as the
13065     *    first arg: dump that one provider
13066     *  - the first arg isn't the flattened component name of an existing provider:
13067     *    dump all providers whose component contains the first arg as a substring
13068     */
13069    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13070            int opti, boolean dumpAll) {
13071        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13072    }
13073
13074    static class ItemMatcher {
13075        ArrayList<ComponentName> components;
13076        ArrayList<String> strings;
13077        ArrayList<Integer> objects;
13078        boolean all;
13079
13080        ItemMatcher() {
13081            all = true;
13082        }
13083
13084        void build(String name) {
13085            ComponentName componentName = ComponentName.unflattenFromString(name);
13086            if (componentName != null) {
13087                if (components == null) {
13088                    components = new ArrayList<ComponentName>();
13089                }
13090                components.add(componentName);
13091                all = false;
13092            } else {
13093                int objectId = 0;
13094                // Not a '/' separated full component name; maybe an object ID?
13095                try {
13096                    objectId = Integer.parseInt(name, 16);
13097                    if (objects == null) {
13098                        objects = new ArrayList<Integer>();
13099                    }
13100                    objects.add(objectId);
13101                    all = false;
13102                } catch (RuntimeException e) {
13103                    // Not an integer; just do string match.
13104                    if (strings == null) {
13105                        strings = new ArrayList<String>();
13106                    }
13107                    strings.add(name);
13108                    all = false;
13109                }
13110            }
13111        }
13112
13113        int build(String[] args, int opti) {
13114            for (; opti<args.length; opti++) {
13115                String name = args[opti];
13116                if ("--".equals(name)) {
13117                    return opti+1;
13118                }
13119                build(name);
13120            }
13121            return opti;
13122        }
13123
13124        boolean match(Object object, ComponentName comp) {
13125            if (all) {
13126                return true;
13127            }
13128            if (components != null) {
13129                for (int i=0; i<components.size(); i++) {
13130                    if (components.get(i).equals(comp)) {
13131                        return true;
13132                    }
13133                }
13134            }
13135            if (objects != null) {
13136                for (int i=0; i<objects.size(); i++) {
13137                    if (System.identityHashCode(object) == objects.get(i)) {
13138                        return true;
13139                    }
13140                }
13141            }
13142            if (strings != null) {
13143                String flat = comp.flattenToString();
13144                for (int i=0; i<strings.size(); i++) {
13145                    if (flat.contains(strings.get(i))) {
13146                        return true;
13147                    }
13148                }
13149            }
13150            return false;
13151        }
13152    }
13153
13154    /**
13155     * There are three things that cmd can be:
13156     *  - a flattened component name that matches an existing activity
13157     *  - the cmd arg isn't the flattened component name of an existing activity:
13158     *    dump all activity whose component contains the cmd as a substring
13159     *  - A hex number of the ActivityRecord object instance.
13160     */
13161    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13162            int opti, boolean dumpAll) {
13163        ArrayList<ActivityRecord> activities;
13164
13165        synchronized (this) {
13166            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13167        }
13168
13169        if (activities.size() <= 0) {
13170            return false;
13171        }
13172
13173        String[] newArgs = new String[args.length - opti];
13174        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13175
13176        TaskRecord lastTask = null;
13177        boolean needSep = false;
13178        for (int i=activities.size()-1; i>=0; i--) {
13179            ActivityRecord r = activities.get(i);
13180            if (needSep) {
13181                pw.println();
13182            }
13183            needSep = true;
13184            synchronized (this) {
13185                if (lastTask != r.task) {
13186                    lastTask = r.task;
13187                    pw.print("TASK "); pw.print(lastTask.affinity);
13188                            pw.print(" id="); pw.println(lastTask.taskId);
13189                    if (dumpAll) {
13190                        lastTask.dump(pw, "  ");
13191                    }
13192                }
13193            }
13194            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13195        }
13196        return true;
13197    }
13198
13199    /**
13200     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13201     * there is a thread associated with the activity.
13202     */
13203    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13204            final ActivityRecord r, String[] args, boolean dumpAll) {
13205        String innerPrefix = prefix + "  ";
13206        synchronized (this) {
13207            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13208                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13209                    pw.print(" pid=");
13210                    if (r.app != null) pw.println(r.app.pid);
13211                    else pw.println("(not running)");
13212            if (dumpAll) {
13213                r.dump(pw, innerPrefix);
13214            }
13215        }
13216        if (r.app != null && r.app.thread != null) {
13217            // flush anything that is already in the PrintWriter since the thread is going
13218            // to write to the file descriptor directly
13219            pw.flush();
13220            try {
13221                TransferPipe tp = new TransferPipe();
13222                try {
13223                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13224                            r.appToken, innerPrefix, args);
13225                    tp.go(fd);
13226                } finally {
13227                    tp.kill();
13228                }
13229            } catch (IOException e) {
13230                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13231            } catch (RemoteException e) {
13232                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13233            }
13234        }
13235    }
13236
13237    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13238            int opti, boolean dumpAll, String dumpPackage) {
13239        boolean needSep = false;
13240        boolean onlyHistory = false;
13241        boolean printedAnything = false;
13242
13243        if ("history".equals(dumpPackage)) {
13244            if (opti < args.length && "-s".equals(args[opti])) {
13245                dumpAll = false;
13246            }
13247            onlyHistory = true;
13248            dumpPackage = null;
13249        }
13250
13251        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13252        if (!onlyHistory && dumpAll) {
13253            if (mRegisteredReceivers.size() > 0) {
13254                boolean printed = false;
13255                Iterator it = mRegisteredReceivers.values().iterator();
13256                while (it.hasNext()) {
13257                    ReceiverList r = (ReceiverList)it.next();
13258                    if (dumpPackage != null && (r.app == null ||
13259                            !dumpPackage.equals(r.app.info.packageName))) {
13260                        continue;
13261                    }
13262                    if (!printed) {
13263                        pw.println("  Registered Receivers:");
13264                        needSep = true;
13265                        printed = true;
13266                        printedAnything = true;
13267                    }
13268                    pw.print("  * "); pw.println(r);
13269                    r.dump(pw, "    ");
13270                }
13271            }
13272
13273            if (mReceiverResolver.dump(pw, needSep ?
13274                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13275                    "    ", dumpPackage, false, false)) {
13276                needSep = true;
13277                printedAnything = true;
13278            }
13279        }
13280
13281        for (BroadcastQueue q : mBroadcastQueues) {
13282            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13283            printedAnything |= needSep;
13284        }
13285
13286        needSep = true;
13287
13288        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13289            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13290                if (needSep) {
13291                    pw.println();
13292                }
13293                needSep = true;
13294                printedAnything = true;
13295                pw.print("  Sticky broadcasts for user ");
13296                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13297                StringBuilder sb = new StringBuilder(128);
13298                for (Map.Entry<String, ArrayList<Intent>> ent
13299                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13300                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13301                    if (dumpAll) {
13302                        pw.println(":");
13303                        ArrayList<Intent> intents = ent.getValue();
13304                        final int N = intents.size();
13305                        for (int i=0; i<N; i++) {
13306                            sb.setLength(0);
13307                            sb.append("    Intent: ");
13308                            intents.get(i).toShortString(sb, false, true, false, false);
13309                            pw.println(sb.toString());
13310                            Bundle bundle = intents.get(i).getExtras();
13311                            if (bundle != null) {
13312                                pw.print("      ");
13313                                pw.println(bundle.toString());
13314                            }
13315                        }
13316                    } else {
13317                        pw.println("");
13318                    }
13319                }
13320            }
13321        }
13322
13323        if (!onlyHistory && dumpAll) {
13324            pw.println();
13325            for (BroadcastQueue queue : mBroadcastQueues) {
13326                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13327                        + queue.mBroadcastsScheduled);
13328            }
13329            pw.println("  mHandler:");
13330            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13331            needSep = true;
13332            printedAnything = true;
13333        }
13334
13335        if (!printedAnything) {
13336            pw.println("  (nothing)");
13337        }
13338    }
13339
13340    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13341            int opti, boolean dumpAll, String dumpPackage) {
13342        boolean needSep;
13343        boolean printedAnything = false;
13344
13345        ItemMatcher matcher = new ItemMatcher();
13346        matcher.build(args, opti);
13347
13348        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13349
13350        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13351        printedAnything |= needSep;
13352
13353        if (mLaunchingProviders.size() > 0) {
13354            boolean printed = false;
13355            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13356                ContentProviderRecord r = mLaunchingProviders.get(i);
13357                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13358                    continue;
13359                }
13360                if (!printed) {
13361                    if (needSep) pw.println();
13362                    needSep = true;
13363                    pw.println("  Launching content providers:");
13364                    printed = true;
13365                    printedAnything = true;
13366                }
13367                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13368                        pw.println(r);
13369            }
13370        }
13371
13372        if (mGrantedUriPermissions.size() > 0) {
13373            boolean printed = false;
13374            int dumpUid = -2;
13375            if (dumpPackage != null) {
13376                try {
13377                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13378                } catch (NameNotFoundException e) {
13379                    dumpUid = -1;
13380                }
13381            }
13382            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13383                int uid = mGrantedUriPermissions.keyAt(i);
13384                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13385                    continue;
13386                }
13387                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13388                if (!printed) {
13389                    if (needSep) pw.println();
13390                    needSep = true;
13391                    pw.println("  Granted Uri Permissions:");
13392                    printed = true;
13393                    printedAnything = true;
13394                }
13395                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13396                for (UriPermission perm : perms.values()) {
13397                    pw.print("    "); pw.println(perm);
13398                    if (dumpAll) {
13399                        perm.dump(pw, "      ");
13400                    }
13401                }
13402            }
13403        }
13404
13405        if (!printedAnything) {
13406            pw.println("  (nothing)");
13407        }
13408    }
13409
13410    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13411            int opti, boolean dumpAll, String dumpPackage) {
13412        boolean printed = false;
13413
13414        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13415
13416        if (mIntentSenderRecords.size() > 0) {
13417            Iterator<WeakReference<PendingIntentRecord>> it
13418                    = mIntentSenderRecords.values().iterator();
13419            while (it.hasNext()) {
13420                WeakReference<PendingIntentRecord> ref = it.next();
13421                PendingIntentRecord rec = ref != null ? ref.get(): null;
13422                if (dumpPackage != null && (rec == null
13423                        || !dumpPackage.equals(rec.key.packageName))) {
13424                    continue;
13425                }
13426                printed = true;
13427                if (rec != null) {
13428                    pw.print("  * "); pw.println(rec);
13429                    if (dumpAll) {
13430                        rec.dump(pw, "    ");
13431                    }
13432                } else {
13433                    pw.print("  * "); pw.println(ref);
13434                }
13435            }
13436        }
13437
13438        if (!printed) {
13439            pw.println("  (nothing)");
13440        }
13441    }
13442
13443    private static final int dumpProcessList(PrintWriter pw,
13444            ActivityManagerService service, List list,
13445            String prefix, String normalLabel, String persistentLabel,
13446            String dumpPackage) {
13447        int numPers = 0;
13448        final int N = list.size()-1;
13449        for (int i=N; i>=0; i--) {
13450            ProcessRecord r = (ProcessRecord)list.get(i);
13451            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13452                continue;
13453            }
13454            pw.println(String.format("%s%s #%2d: %s",
13455                    prefix, (r.persistent ? persistentLabel : normalLabel),
13456                    i, r.toString()));
13457            if (r.persistent) {
13458                numPers++;
13459            }
13460        }
13461        return numPers;
13462    }
13463
13464    private static final boolean dumpProcessOomList(PrintWriter pw,
13465            ActivityManagerService service, List<ProcessRecord> origList,
13466            String prefix, String normalLabel, String persistentLabel,
13467            boolean inclDetails, String dumpPackage) {
13468
13469        ArrayList<Pair<ProcessRecord, Integer>> list
13470                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13471        for (int i=0; i<origList.size(); i++) {
13472            ProcessRecord r = origList.get(i);
13473            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13474                continue;
13475            }
13476            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13477        }
13478
13479        if (list.size() <= 0) {
13480            return false;
13481        }
13482
13483        Comparator<Pair<ProcessRecord, Integer>> comparator
13484                = new Comparator<Pair<ProcessRecord, Integer>>() {
13485            @Override
13486            public int compare(Pair<ProcessRecord, Integer> object1,
13487                    Pair<ProcessRecord, Integer> object2) {
13488                if (object1.first.setAdj != object2.first.setAdj) {
13489                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13490                }
13491                if (object1.second.intValue() != object2.second.intValue()) {
13492                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13493                }
13494                return 0;
13495            }
13496        };
13497
13498        Collections.sort(list, comparator);
13499
13500        final long curRealtime = SystemClock.elapsedRealtime();
13501        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13502        final long curUptime = SystemClock.uptimeMillis();
13503        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13504
13505        for (int i=list.size()-1; i>=0; i--) {
13506            ProcessRecord r = list.get(i).first;
13507            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13508            char schedGroup;
13509            switch (r.setSchedGroup) {
13510                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13511                    schedGroup = 'B';
13512                    break;
13513                case Process.THREAD_GROUP_DEFAULT:
13514                    schedGroup = 'F';
13515                    break;
13516                default:
13517                    schedGroup = '?';
13518                    break;
13519            }
13520            char foreground;
13521            if (r.foregroundActivities) {
13522                foreground = 'A';
13523            } else if (r.foregroundServices) {
13524                foreground = 'S';
13525            } else {
13526                foreground = ' ';
13527            }
13528            String procState = ProcessList.makeProcStateString(r.curProcState);
13529            pw.print(prefix);
13530            pw.print(r.persistent ? persistentLabel : normalLabel);
13531            pw.print(" #");
13532            int num = (origList.size()-1)-list.get(i).second;
13533            if (num < 10) pw.print(' ');
13534            pw.print(num);
13535            pw.print(": ");
13536            pw.print(oomAdj);
13537            pw.print(' ');
13538            pw.print(schedGroup);
13539            pw.print('/');
13540            pw.print(foreground);
13541            pw.print('/');
13542            pw.print(procState);
13543            pw.print(" trm:");
13544            if (r.trimMemoryLevel < 10) pw.print(' ');
13545            pw.print(r.trimMemoryLevel);
13546            pw.print(' ');
13547            pw.print(r.toShortString());
13548            pw.print(" (");
13549            pw.print(r.adjType);
13550            pw.println(')');
13551            if (r.adjSource != null || r.adjTarget != null) {
13552                pw.print(prefix);
13553                pw.print("    ");
13554                if (r.adjTarget instanceof ComponentName) {
13555                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13556                } else if (r.adjTarget != null) {
13557                    pw.print(r.adjTarget.toString());
13558                } else {
13559                    pw.print("{null}");
13560                }
13561                pw.print("<=");
13562                if (r.adjSource instanceof ProcessRecord) {
13563                    pw.print("Proc{");
13564                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13565                    pw.println("}");
13566                } else if (r.adjSource != null) {
13567                    pw.println(r.adjSource.toString());
13568                } else {
13569                    pw.println("{null}");
13570                }
13571            }
13572            if (inclDetails) {
13573                pw.print(prefix);
13574                pw.print("    ");
13575                pw.print("oom: max="); pw.print(r.maxAdj);
13576                pw.print(" curRaw="); pw.print(r.curRawAdj);
13577                pw.print(" setRaw="); pw.print(r.setRawAdj);
13578                pw.print(" cur="); pw.print(r.curAdj);
13579                pw.print(" set="); pw.println(r.setAdj);
13580                pw.print(prefix);
13581                pw.print("    ");
13582                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13583                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13584                pw.print(" lastPss="); pw.print(r.lastPss);
13585                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13586                pw.print(prefix);
13587                pw.print("    ");
13588                pw.print("cached="); pw.print(r.cached);
13589                pw.print(" empty="); pw.print(r.empty);
13590                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13591
13592                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13593                    if (r.lastWakeTime != 0) {
13594                        long wtime;
13595                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13596                        synchronized (stats) {
13597                            wtime = stats.getProcessWakeTime(r.info.uid,
13598                                    r.pid, curRealtime);
13599                        }
13600                        long timeUsed = wtime - r.lastWakeTime;
13601                        pw.print(prefix);
13602                        pw.print("    ");
13603                        pw.print("keep awake over ");
13604                        TimeUtils.formatDuration(realtimeSince, pw);
13605                        pw.print(" used ");
13606                        TimeUtils.formatDuration(timeUsed, pw);
13607                        pw.print(" (");
13608                        pw.print((timeUsed*100)/realtimeSince);
13609                        pw.println("%)");
13610                    }
13611                    if (r.lastCpuTime != 0) {
13612                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13613                        pw.print(prefix);
13614                        pw.print("    ");
13615                        pw.print("run cpu over ");
13616                        TimeUtils.formatDuration(uptimeSince, pw);
13617                        pw.print(" used ");
13618                        TimeUtils.formatDuration(timeUsed, pw);
13619                        pw.print(" (");
13620                        pw.print((timeUsed*100)/uptimeSince);
13621                        pw.println("%)");
13622                    }
13623                }
13624            }
13625        }
13626        return true;
13627    }
13628
13629    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13630            String[] args) {
13631        ArrayList<ProcessRecord> procs;
13632        synchronized (this) {
13633            if (args != null && args.length > start
13634                    && args[start].charAt(0) != '-') {
13635                procs = new ArrayList<ProcessRecord>();
13636                int pid = -1;
13637                try {
13638                    pid = Integer.parseInt(args[start]);
13639                } catch (NumberFormatException e) {
13640                }
13641                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13642                    ProcessRecord proc = mLruProcesses.get(i);
13643                    if (proc.pid == pid) {
13644                        procs.add(proc);
13645                    } else if (allPkgs && proc.pkgList != null
13646                            && proc.pkgList.containsKey(args[start])) {
13647                        procs.add(proc);
13648                    } else if (proc.processName.equals(args[start])) {
13649                        procs.add(proc);
13650                    }
13651                }
13652                if (procs.size() <= 0) {
13653                    return null;
13654                }
13655            } else {
13656                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13657            }
13658        }
13659        return procs;
13660    }
13661
13662    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13663            PrintWriter pw, String[] args) {
13664        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13665        if (procs == null) {
13666            pw.println("No process found for: " + args[0]);
13667            return;
13668        }
13669
13670        long uptime = SystemClock.uptimeMillis();
13671        long realtime = SystemClock.elapsedRealtime();
13672        pw.println("Applications Graphics Acceleration Info:");
13673        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13674
13675        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13676            ProcessRecord r = procs.get(i);
13677            if (r.thread != null) {
13678                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13679                pw.flush();
13680                try {
13681                    TransferPipe tp = new TransferPipe();
13682                    try {
13683                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13684                        tp.go(fd);
13685                    } finally {
13686                        tp.kill();
13687                    }
13688                } catch (IOException e) {
13689                    pw.println("Failure while dumping the app: " + r);
13690                    pw.flush();
13691                } catch (RemoteException e) {
13692                    pw.println("Got a RemoteException while dumping the app " + r);
13693                    pw.flush();
13694                }
13695            }
13696        }
13697    }
13698
13699    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13700        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13701        if (procs == null) {
13702            pw.println("No process found for: " + args[0]);
13703            return;
13704        }
13705
13706        pw.println("Applications Database Info:");
13707
13708        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13709            ProcessRecord r = procs.get(i);
13710            if (r.thread != null) {
13711                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13712                pw.flush();
13713                try {
13714                    TransferPipe tp = new TransferPipe();
13715                    try {
13716                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13717                        tp.go(fd);
13718                    } finally {
13719                        tp.kill();
13720                    }
13721                } catch (IOException e) {
13722                    pw.println("Failure while dumping the app: " + r);
13723                    pw.flush();
13724                } catch (RemoteException e) {
13725                    pw.println("Got a RemoteException while dumping the app " + r);
13726                    pw.flush();
13727                }
13728            }
13729        }
13730    }
13731
13732    final static class MemItem {
13733        final boolean isProc;
13734        final String label;
13735        final String shortLabel;
13736        final long pss;
13737        final int id;
13738        final boolean hasActivities;
13739        ArrayList<MemItem> subitems;
13740
13741        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13742                boolean _hasActivities) {
13743            isProc = true;
13744            label = _label;
13745            shortLabel = _shortLabel;
13746            pss = _pss;
13747            id = _id;
13748            hasActivities = _hasActivities;
13749        }
13750
13751        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13752            isProc = false;
13753            label = _label;
13754            shortLabel = _shortLabel;
13755            pss = _pss;
13756            id = _id;
13757            hasActivities = false;
13758        }
13759    }
13760
13761    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13762            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13763        if (sort && !isCompact) {
13764            Collections.sort(items, new Comparator<MemItem>() {
13765                @Override
13766                public int compare(MemItem lhs, MemItem rhs) {
13767                    if (lhs.pss < rhs.pss) {
13768                        return 1;
13769                    } else if (lhs.pss > rhs.pss) {
13770                        return -1;
13771                    }
13772                    return 0;
13773                }
13774            });
13775        }
13776
13777        for (int i=0; i<items.size(); i++) {
13778            MemItem mi = items.get(i);
13779            if (!isCompact) {
13780                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13781            } else if (mi.isProc) {
13782                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13783                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13784                pw.println(mi.hasActivities ? ",a" : ",e");
13785            } else {
13786                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13787                pw.println(mi.pss);
13788            }
13789            if (mi.subitems != null) {
13790                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13791                        true, isCompact);
13792            }
13793        }
13794    }
13795
13796    // These are in KB.
13797    static final long[] DUMP_MEM_BUCKETS = new long[] {
13798        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13799        120*1024, 160*1024, 200*1024,
13800        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13801        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13802    };
13803
13804    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13805            boolean stackLike) {
13806        int start = label.lastIndexOf('.');
13807        if (start >= 0) start++;
13808        else start = 0;
13809        int end = label.length();
13810        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13811            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13812                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13813                out.append(bucket);
13814                out.append(stackLike ? "MB." : "MB ");
13815                out.append(label, start, end);
13816                return;
13817            }
13818        }
13819        out.append(memKB/1024);
13820        out.append(stackLike ? "MB." : "MB ");
13821        out.append(label, start, end);
13822    }
13823
13824    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13825            ProcessList.NATIVE_ADJ,
13826            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13827            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13828            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13829            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13830            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13831            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13832    };
13833    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13834            "Native",
13835            "System", "Persistent", "Persistent Service", "Foreground",
13836            "Visible", "Perceptible",
13837            "Heavy Weight", "Backup",
13838            "A Services", "Home",
13839            "Previous", "B Services", "Cached"
13840    };
13841    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13842            "native",
13843            "sys", "pers", "persvc", "fore",
13844            "vis", "percept",
13845            "heavy", "backup",
13846            "servicea", "home",
13847            "prev", "serviceb", "cached"
13848    };
13849
13850    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13851            long realtime, boolean isCheckinRequest, boolean isCompact) {
13852        if (isCheckinRequest || isCompact) {
13853            // short checkin version
13854            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13855        } else {
13856            pw.println("Applications Memory Usage (kB):");
13857            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13858        }
13859    }
13860
13861    private static final int KSM_SHARED = 0;
13862    private static final int KSM_SHARING = 1;
13863    private static final int KSM_UNSHARED = 2;
13864    private static final int KSM_VOLATILE = 3;
13865
13866    private final long[] getKsmInfo() {
13867        long[] longOut = new long[4];
13868        final int[] SINGLE_LONG_FORMAT = new int[] {
13869            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13870        };
13871        long[] longTmp = new long[1];
13872        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13873                SINGLE_LONG_FORMAT, null, longTmp, null);
13874        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13875        longTmp[0] = 0;
13876        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13877                SINGLE_LONG_FORMAT, null, longTmp, null);
13878        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13879        longTmp[0] = 0;
13880        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13881                SINGLE_LONG_FORMAT, null, longTmp, null);
13882        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13883        longTmp[0] = 0;
13884        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13885                SINGLE_LONG_FORMAT, null, longTmp, null);
13886        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13887        return longOut;
13888    }
13889
13890    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13891            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13892        boolean dumpDetails = false;
13893        boolean dumpFullDetails = false;
13894        boolean dumpDalvik = false;
13895        boolean oomOnly = false;
13896        boolean isCompact = false;
13897        boolean localOnly = false;
13898        boolean packages = false;
13899
13900        int opti = 0;
13901        while (opti < args.length) {
13902            String opt = args[opti];
13903            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13904                break;
13905            }
13906            opti++;
13907            if ("-a".equals(opt)) {
13908                dumpDetails = true;
13909                dumpFullDetails = true;
13910                dumpDalvik = true;
13911            } else if ("-d".equals(opt)) {
13912                dumpDalvik = true;
13913            } else if ("-c".equals(opt)) {
13914                isCompact = true;
13915            } else if ("--oom".equals(opt)) {
13916                oomOnly = true;
13917            } else if ("--local".equals(opt)) {
13918                localOnly = true;
13919            } else if ("--package".equals(opt)) {
13920                packages = true;
13921            } else if ("-h".equals(opt)) {
13922                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13923                pw.println("  -a: include all available information for each process.");
13924                pw.println("  -d: include dalvik details when dumping process details.");
13925                pw.println("  -c: dump in a compact machine-parseable representation.");
13926                pw.println("  --oom: only show processes organized by oom adj.");
13927                pw.println("  --local: only collect details locally, don't call process.");
13928                pw.println("  --package: interpret process arg as package, dumping all");
13929                pw.println("             processes that have loaded that package.");
13930                pw.println("If [process] is specified it can be the name or ");
13931                pw.println("pid of a specific process to dump.");
13932                return;
13933            } else {
13934                pw.println("Unknown argument: " + opt + "; use -h for help");
13935            }
13936        }
13937
13938        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13939        long uptime = SystemClock.uptimeMillis();
13940        long realtime = SystemClock.elapsedRealtime();
13941        final long[] tmpLong = new long[1];
13942
13943        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13944        if (procs == null) {
13945            // No Java processes.  Maybe they want to print a native process.
13946            if (args != null && args.length > opti
13947                    && args[opti].charAt(0) != '-') {
13948                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13949                        = new ArrayList<ProcessCpuTracker.Stats>();
13950                updateCpuStatsNow();
13951                int findPid = -1;
13952                try {
13953                    findPid = Integer.parseInt(args[opti]);
13954                } catch (NumberFormatException e) {
13955                }
13956                synchronized (mProcessCpuTracker) {
13957                    final int N = mProcessCpuTracker.countStats();
13958                    for (int i=0; i<N; i++) {
13959                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13960                        if (st.pid == findPid || (st.baseName != null
13961                                && st.baseName.equals(args[opti]))) {
13962                            nativeProcs.add(st);
13963                        }
13964                    }
13965                }
13966                if (nativeProcs.size() > 0) {
13967                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13968                            isCompact);
13969                    Debug.MemoryInfo mi = null;
13970                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13971                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13972                        final int pid = r.pid;
13973                        if (!isCheckinRequest && dumpDetails) {
13974                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13975                        }
13976                        if (mi == null) {
13977                            mi = new Debug.MemoryInfo();
13978                        }
13979                        if (dumpDetails || (!brief && !oomOnly)) {
13980                            Debug.getMemoryInfo(pid, mi);
13981                        } else {
13982                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13983                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13984                        }
13985                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13986                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13987                        if (isCheckinRequest) {
13988                            pw.println();
13989                        }
13990                    }
13991                    return;
13992                }
13993            }
13994            pw.println("No process found for: " + args[opti]);
13995            return;
13996        }
13997
13998        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13999            dumpDetails = true;
14000        }
14001
14002        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14003
14004        String[] innerArgs = new String[args.length-opti];
14005        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14006
14007        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14008        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14009        long nativePss = 0;
14010        long dalvikPss = 0;
14011        long otherPss = 0;
14012        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14013
14014        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14015        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14016                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14017
14018        long totalPss = 0;
14019        long cachedPss = 0;
14020
14021        Debug.MemoryInfo mi = null;
14022        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14023            final ProcessRecord r = procs.get(i);
14024            final IApplicationThread thread;
14025            final int pid;
14026            final int oomAdj;
14027            final boolean hasActivities;
14028            synchronized (this) {
14029                thread = r.thread;
14030                pid = r.pid;
14031                oomAdj = r.getSetAdjWithServices();
14032                hasActivities = r.activities.size() > 0;
14033            }
14034            if (thread != null) {
14035                if (!isCheckinRequest && dumpDetails) {
14036                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14037                }
14038                if (mi == null) {
14039                    mi = new Debug.MemoryInfo();
14040                }
14041                if (dumpDetails || (!brief && !oomOnly)) {
14042                    Debug.getMemoryInfo(pid, mi);
14043                } else {
14044                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14045                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14046                }
14047                if (dumpDetails) {
14048                    if (localOnly) {
14049                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14050                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14051                        if (isCheckinRequest) {
14052                            pw.println();
14053                        }
14054                    } else {
14055                        try {
14056                            pw.flush();
14057                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14058                                    dumpDalvik, innerArgs);
14059                        } catch (RemoteException e) {
14060                            if (!isCheckinRequest) {
14061                                pw.println("Got RemoteException!");
14062                                pw.flush();
14063                            }
14064                        }
14065                    }
14066                }
14067
14068                final long myTotalPss = mi.getTotalPss();
14069                final long myTotalUss = mi.getTotalUss();
14070
14071                synchronized (this) {
14072                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14073                        // Record this for posterity if the process has been stable.
14074                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14075                    }
14076                }
14077
14078                if (!isCheckinRequest && mi != null) {
14079                    totalPss += myTotalPss;
14080                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14081                            (hasActivities ? " / activities)" : ")"),
14082                            r.processName, myTotalPss, pid, hasActivities);
14083                    procMems.add(pssItem);
14084                    procMemsMap.put(pid, pssItem);
14085
14086                    nativePss += mi.nativePss;
14087                    dalvikPss += mi.dalvikPss;
14088                    otherPss += mi.otherPss;
14089                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14090                        long mem = mi.getOtherPss(j);
14091                        miscPss[j] += mem;
14092                        otherPss -= mem;
14093                    }
14094
14095                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14096                        cachedPss += myTotalPss;
14097                    }
14098
14099                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14100                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14101                                || oomIndex == (oomPss.length-1)) {
14102                            oomPss[oomIndex] += myTotalPss;
14103                            if (oomProcs[oomIndex] == null) {
14104                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14105                            }
14106                            oomProcs[oomIndex].add(pssItem);
14107                            break;
14108                        }
14109                    }
14110                }
14111            }
14112        }
14113
14114        long nativeProcTotalPss = 0;
14115
14116        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14117            // If we are showing aggregations, also look for native processes to
14118            // include so that our aggregations are more accurate.
14119            updateCpuStatsNow();
14120            synchronized (mProcessCpuTracker) {
14121                final int N = mProcessCpuTracker.countStats();
14122                for (int i=0; i<N; i++) {
14123                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14124                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14125                        if (mi == null) {
14126                            mi = new Debug.MemoryInfo();
14127                        }
14128                        if (!brief && !oomOnly) {
14129                            Debug.getMemoryInfo(st.pid, mi);
14130                        } else {
14131                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14132                            mi.nativePrivateDirty = (int)tmpLong[0];
14133                        }
14134
14135                        final long myTotalPss = mi.getTotalPss();
14136                        totalPss += myTotalPss;
14137                        nativeProcTotalPss += myTotalPss;
14138
14139                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14140                                st.name, myTotalPss, st.pid, false);
14141                        procMems.add(pssItem);
14142
14143                        nativePss += mi.nativePss;
14144                        dalvikPss += mi.dalvikPss;
14145                        otherPss += mi.otherPss;
14146                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14147                            long mem = mi.getOtherPss(j);
14148                            miscPss[j] += mem;
14149                            otherPss -= mem;
14150                        }
14151                        oomPss[0] += myTotalPss;
14152                        if (oomProcs[0] == null) {
14153                            oomProcs[0] = new ArrayList<MemItem>();
14154                        }
14155                        oomProcs[0].add(pssItem);
14156                    }
14157                }
14158            }
14159
14160            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14161
14162            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14163            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14164            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14165            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14166                String label = Debug.MemoryInfo.getOtherLabel(j);
14167                catMems.add(new MemItem(label, label, miscPss[j], j));
14168            }
14169
14170            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14171            for (int j=0; j<oomPss.length; j++) {
14172                if (oomPss[j] != 0) {
14173                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14174                            : DUMP_MEM_OOM_LABEL[j];
14175                    MemItem item = new MemItem(label, label, oomPss[j],
14176                            DUMP_MEM_OOM_ADJ[j]);
14177                    item.subitems = oomProcs[j];
14178                    oomMems.add(item);
14179                }
14180            }
14181
14182            if (!brief && !oomOnly && !isCompact) {
14183                pw.println();
14184                pw.println("Total PSS by process:");
14185                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14186                pw.println();
14187            }
14188            if (!isCompact) {
14189                pw.println("Total PSS by OOM adjustment:");
14190            }
14191            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14192            if (!brief && !oomOnly) {
14193                PrintWriter out = categoryPw != null ? categoryPw : pw;
14194                if (!isCompact) {
14195                    out.println();
14196                    out.println("Total PSS by category:");
14197                }
14198                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14199            }
14200            if (!isCompact) {
14201                pw.println();
14202            }
14203            MemInfoReader memInfo = new MemInfoReader();
14204            memInfo.readMemInfo();
14205            if (nativeProcTotalPss > 0) {
14206                synchronized (this) {
14207                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14208                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14209                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14210                }
14211            }
14212            if (!brief) {
14213                if (!isCompact) {
14214                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14215                    pw.print(" kB (status ");
14216                    switch (mLastMemoryLevel) {
14217                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14218                            pw.println("normal)");
14219                            break;
14220                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14221                            pw.println("moderate)");
14222                            break;
14223                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14224                            pw.println("low)");
14225                            break;
14226                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14227                            pw.println("critical)");
14228                            break;
14229                        default:
14230                            pw.print(mLastMemoryLevel);
14231                            pw.println(")");
14232                            break;
14233                    }
14234                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14235                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14236                            pw.print(cachedPss); pw.print(" cached pss + ");
14237                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14238                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14239                } else {
14240                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14241                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14242                            + memInfo.getFreeSizeKb()); pw.print(",");
14243                    pw.println(totalPss - cachedPss);
14244                }
14245            }
14246            if (!isCompact) {
14247                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14248                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14249                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14250                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14251                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14252                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14253                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14254            }
14255            if (!brief) {
14256                if (memInfo.getZramTotalSizeKb() != 0) {
14257                    if (!isCompact) {
14258                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14259                                pw.print(" kB physical used for ");
14260                                pw.print(memInfo.getSwapTotalSizeKb()
14261                                        - memInfo.getSwapFreeSizeKb());
14262                                pw.print(" kB in swap (");
14263                                pw.print(memInfo.getSwapTotalSizeKb());
14264                                pw.println(" kB total swap)");
14265                    } else {
14266                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14267                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14268                                pw.println(memInfo.getSwapFreeSizeKb());
14269                    }
14270                }
14271                final long[] ksm = getKsmInfo();
14272                if (!isCompact) {
14273                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14274                            || ksm[KSM_VOLATILE] != 0) {
14275                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14276                                pw.print(" kB saved from shared ");
14277                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14278                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14279                                pw.print(" kB unshared; ");
14280                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14281                    }
14282                    pw.print("   Tuning: ");
14283                    pw.print(ActivityManager.staticGetMemoryClass());
14284                    pw.print(" (large ");
14285                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14286                    pw.print("), oom ");
14287                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14288                    pw.print(" kB");
14289                    pw.print(", restore limit ");
14290                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14291                    pw.print(" kB");
14292                    if (ActivityManager.isLowRamDeviceStatic()) {
14293                        pw.print(" (low-ram)");
14294                    }
14295                    if (ActivityManager.isHighEndGfx()) {
14296                        pw.print(" (high-end-gfx)");
14297                    }
14298                    pw.println();
14299                } else {
14300                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14301                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14302                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14303                    pw.print("tuning,");
14304                    pw.print(ActivityManager.staticGetMemoryClass());
14305                    pw.print(',');
14306                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14307                    pw.print(',');
14308                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14309                    if (ActivityManager.isLowRamDeviceStatic()) {
14310                        pw.print(",low-ram");
14311                    }
14312                    if (ActivityManager.isHighEndGfx()) {
14313                        pw.print(",high-end-gfx");
14314                    }
14315                    pw.println();
14316                }
14317            }
14318        }
14319    }
14320
14321    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14322            String name) {
14323        sb.append("  ");
14324        sb.append(ProcessList.makeOomAdjString(oomAdj));
14325        sb.append(' ');
14326        sb.append(ProcessList.makeProcStateString(procState));
14327        sb.append(' ');
14328        ProcessList.appendRamKb(sb, pss);
14329        sb.append(" kB: ");
14330        sb.append(name);
14331    }
14332
14333    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14334        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14335        sb.append(" (");
14336        sb.append(mi.pid);
14337        sb.append(") ");
14338        sb.append(mi.adjType);
14339        sb.append('\n');
14340        if (mi.adjReason != null) {
14341            sb.append("                      ");
14342            sb.append(mi.adjReason);
14343            sb.append('\n');
14344        }
14345    }
14346
14347    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14348        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14349        for (int i=0, N=memInfos.size(); i<N; i++) {
14350            ProcessMemInfo mi = memInfos.get(i);
14351            infoMap.put(mi.pid, mi);
14352        }
14353        updateCpuStatsNow();
14354        synchronized (mProcessCpuTracker) {
14355            final int N = mProcessCpuTracker.countStats();
14356            for (int i=0; i<N; i++) {
14357                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14358                if (st.vsize > 0) {
14359                    long pss = Debug.getPss(st.pid, null);
14360                    if (pss > 0) {
14361                        if (infoMap.indexOfKey(st.pid) < 0) {
14362                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14363                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14364                            mi.pss = pss;
14365                            memInfos.add(mi);
14366                        }
14367                    }
14368                }
14369            }
14370        }
14371
14372        long totalPss = 0;
14373        for (int i=0, N=memInfos.size(); i<N; i++) {
14374            ProcessMemInfo mi = memInfos.get(i);
14375            if (mi.pss == 0) {
14376                mi.pss = Debug.getPss(mi.pid, null);
14377            }
14378            totalPss += mi.pss;
14379        }
14380        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14381            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14382                if (lhs.oomAdj != rhs.oomAdj) {
14383                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14384                }
14385                if (lhs.pss != rhs.pss) {
14386                    return lhs.pss < rhs.pss ? 1 : -1;
14387                }
14388                return 0;
14389            }
14390        });
14391
14392        StringBuilder tag = new StringBuilder(128);
14393        StringBuilder stack = new StringBuilder(128);
14394        tag.append("Low on memory -- ");
14395        appendMemBucket(tag, totalPss, "total", false);
14396        appendMemBucket(stack, totalPss, "total", true);
14397
14398        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14399        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14400        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14401
14402        boolean firstLine = true;
14403        int lastOomAdj = Integer.MIN_VALUE;
14404        long extraNativeRam = 0;
14405        long cachedPss = 0;
14406        for (int i=0, N=memInfos.size(); i<N; i++) {
14407            ProcessMemInfo mi = memInfos.get(i);
14408
14409            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14410                cachedPss += mi.pss;
14411            }
14412
14413            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14414                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14415                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14416                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14417                if (lastOomAdj != mi.oomAdj) {
14418                    lastOomAdj = mi.oomAdj;
14419                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14420                        tag.append(" / ");
14421                    }
14422                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14423                        if (firstLine) {
14424                            stack.append(":");
14425                            firstLine = false;
14426                        }
14427                        stack.append("\n\t at ");
14428                    } else {
14429                        stack.append("$");
14430                    }
14431                } else {
14432                    tag.append(" ");
14433                    stack.append("$");
14434                }
14435                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14436                    appendMemBucket(tag, mi.pss, mi.name, false);
14437                }
14438                appendMemBucket(stack, mi.pss, mi.name, true);
14439                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14440                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14441                    stack.append("(");
14442                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14443                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14444                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14445                            stack.append(":");
14446                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14447                        }
14448                    }
14449                    stack.append(")");
14450                }
14451            }
14452
14453            appendMemInfo(fullNativeBuilder, mi);
14454            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14455                // The short form only has native processes that are >= 1MB.
14456                if (mi.pss >= 1000) {
14457                    appendMemInfo(shortNativeBuilder, mi);
14458                } else {
14459                    extraNativeRam += mi.pss;
14460                }
14461            } else {
14462                // Short form has all other details, but if we have collected RAM
14463                // from smaller native processes let's dump a summary of that.
14464                if (extraNativeRam > 0) {
14465                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14466                            -1, extraNativeRam, "(Other native)");
14467                    shortNativeBuilder.append('\n');
14468                    extraNativeRam = 0;
14469                }
14470                appendMemInfo(fullJavaBuilder, mi);
14471            }
14472        }
14473
14474        fullJavaBuilder.append("           ");
14475        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14476        fullJavaBuilder.append(" kB: TOTAL\n");
14477
14478        MemInfoReader memInfo = new MemInfoReader();
14479        memInfo.readMemInfo();
14480        final long[] infos = memInfo.getRawInfo();
14481
14482        StringBuilder memInfoBuilder = new StringBuilder(1024);
14483        Debug.getMemInfo(infos);
14484        memInfoBuilder.append("  MemInfo: ");
14485        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14486        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14487        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14488        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14489        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14490        memInfoBuilder.append("           ");
14491        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14492        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14493        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14494        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14495        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14496            memInfoBuilder.append("  ZRAM: ");
14497            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14498            memInfoBuilder.append(" kB RAM, ");
14499            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14500            memInfoBuilder.append(" kB swap total, ");
14501            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14502            memInfoBuilder.append(" kB swap free\n");
14503        }
14504        final long[] ksm = getKsmInfo();
14505        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14506                || ksm[KSM_VOLATILE] != 0) {
14507            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14508            memInfoBuilder.append(" kB saved from shared ");
14509            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14510            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14511            memInfoBuilder.append(" kB unshared; ");
14512            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14513        }
14514        memInfoBuilder.append("  Free RAM: ");
14515        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14516                + memInfo.getFreeSizeKb());
14517        memInfoBuilder.append(" kB\n");
14518        memInfoBuilder.append("  Used RAM: ");
14519        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14520        memInfoBuilder.append(" kB\n");
14521        memInfoBuilder.append("  Lost RAM: ");
14522        memInfoBuilder.append(memInfo.getTotalSizeKb()
14523                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14524                - memInfo.getKernelUsedSizeKb());
14525        memInfoBuilder.append(" kB\n");
14526        Slog.i(TAG, "Low on memory:");
14527        Slog.i(TAG, shortNativeBuilder.toString());
14528        Slog.i(TAG, fullJavaBuilder.toString());
14529        Slog.i(TAG, memInfoBuilder.toString());
14530
14531        StringBuilder dropBuilder = new StringBuilder(1024);
14532        /*
14533        StringWriter oomSw = new StringWriter();
14534        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14535        StringWriter catSw = new StringWriter();
14536        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14537        String[] emptyArgs = new String[] { };
14538        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14539        oomPw.flush();
14540        String oomString = oomSw.toString();
14541        */
14542        dropBuilder.append("Low on memory:");
14543        dropBuilder.append(stack);
14544        dropBuilder.append('\n');
14545        dropBuilder.append(fullNativeBuilder);
14546        dropBuilder.append(fullJavaBuilder);
14547        dropBuilder.append('\n');
14548        dropBuilder.append(memInfoBuilder);
14549        dropBuilder.append('\n');
14550        /*
14551        dropBuilder.append(oomString);
14552        dropBuilder.append('\n');
14553        */
14554        StringWriter catSw = new StringWriter();
14555        synchronized (ActivityManagerService.this) {
14556            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14557            String[] emptyArgs = new String[] { };
14558            catPw.println();
14559            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14560            catPw.println();
14561            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14562                    false, false, null);
14563            catPw.println();
14564            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14565            catPw.flush();
14566        }
14567        dropBuilder.append(catSw.toString());
14568        addErrorToDropBox("lowmem", null, "system_server", null,
14569                null, tag.toString(), dropBuilder.toString(), null, null);
14570        //Slog.i(TAG, "Sent to dropbox:");
14571        //Slog.i(TAG, dropBuilder.toString());
14572        synchronized (ActivityManagerService.this) {
14573            long now = SystemClock.uptimeMillis();
14574            if (mLastMemUsageReportTime < now) {
14575                mLastMemUsageReportTime = now;
14576            }
14577        }
14578    }
14579
14580    /**
14581     * Searches array of arguments for the specified string
14582     * @param args array of argument strings
14583     * @param value value to search for
14584     * @return true if the value is contained in the array
14585     */
14586    private static boolean scanArgs(String[] args, String value) {
14587        if (args != null) {
14588            for (String arg : args) {
14589                if (value.equals(arg)) {
14590                    return true;
14591                }
14592            }
14593        }
14594        return false;
14595    }
14596
14597    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14598            ContentProviderRecord cpr, boolean always) {
14599        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14600
14601        if (!inLaunching || always) {
14602            synchronized (cpr) {
14603                cpr.launchingApp = null;
14604                cpr.notifyAll();
14605            }
14606            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14607            String names[] = cpr.info.authority.split(";");
14608            for (int j = 0; j < names.length; j++) {
14609                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14610            }
14611        }
14612
14613        for (int i=0; i<cpr.connections.size(); i++) {
14614            ContentProviderConnection conn = cpr.connections.get(i);
14615            if (conn.waiting) {
14616                // If this connection is waiting for the provider, then we don't
14617                // need to mess with its process unless we are always removing
14618                // or for some reason the provider is not currently launching.
14619                if (inLaunching && !always) {
14620                    continue;
14621                }
14622            }
14623            ProcessRecord capp = conn.client;
14624            conn.dead = true;
14625            if (conn.stableCount > 0) {
14626                if (!capp.persistent && capp.thread != null
14627                        && capp.pid != 0
14628                        && capp.pid != MY_PID) {
14629                    capp.kill("depends on provider "
14630                            + cpr.name.flattenToShortString()
14631                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14632                }
14633            } else if (capp.thread != null && conn.provider.provider != null) {
14634                try {
14635                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14636                } catch (RemoteException e) {
14637                }
14638                // In the protocol here, we don't expect the client to correctly
14639                // clean up this connection, we'll just remove it.
14640                cpr.connections.remove(i);
14641                conn.client.conProviders.remove(conn);
14642            }
14643        }
14644
14645        if (inLaunching && always) {
14646            mLaunchingProviders.remove(cpr);
14647        }
14648        return inLaunching;
14649    }
14650
14651    /**
14652     * Main code for cleaning up a process when it has gone away.  This is
14653     * called both as a result of the process dying, or directly when stopping
14654     * a process when running in single process mode.
14655     *
14656     * @return Returns true if the given process has been restarted, so the
14657     * app that was passed in must remain on the process lists.
14658     */
14659    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14660            boolean restarting, boolean allowRestart, int index) {
14661        if (index >= 0) {
14662            removeLruProcessLocked(app);
14663            ProcessList.remove(app.pid);
14664        }
14665
14666        mProcessesToGc.remove(app);
14667        mPendingPssProcesses.remove(app);
14668
14669        // Dismiss any open dialogs.
14670        if (app.crashDialog != null && !app.forceCrashReport) {
14671            app.crashDialog.dismiss();
14672            app.crashDialog = null;
14673        }
14674        if (app.anrDialog != null) {
14675            app.anrDialog.dismiss();
14676            app.anrDialog = null;
14677        }
14678        if (app.waitDialog != null) {
14679            app.waitDialog.dismiss();
14680            app.waitDialog = null;
14681        }
14682
14683        app.crashing = false;
14684        app.notResponding = false;
14685
14686        app.resetPackageList(mProcessStats);
14687        app.unlinkDeathRecipient();
14688        app.makeInactive(mProcessStats);
14689        app.waitingToKill = null;
14690        app.forcingToForeground = null;
14691        updateProcessForegroundLocked(app, false, false);
14692        app.foregroundActivities = false;
14693        app.hasShownUi = false;
14694        app.treatLikeActivity = false;
14695        app.hasAboveClient = false;
14696        app.hasClientActivities = false;
14697
14698        mServices.killServicesLocked(app, allowRestart);
14699
14700        boolean restart = false;
14701
14702        // Remove published content providers.
14703        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14704            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14705            final boolean always = app.bad || !allowRestart;
14706            if (removeDyingProviderLocked(app, cpr, always) || always) {
14707                // We left the provider in the launching list, need to
14708                // restart it.
14709                restart = true;
14710            }
14711
14712            cpr.provider = null;
14713            cpr.proc = null;
14714        }
14715        app.pubProviders.clear();
14716
14717        // Take care of any launching providers waiting for this process.
14718        if (checkAppInLaunchingProvidersLocked(app, false)) {
14719            restart = true;
14720        }
14721
14722        // Unregister from connected content providers.
14723        if (!app.conProviders.isEmpty()) {
14724            for (int i=0; i<app.conProviders.size(); i++) {
14725                ContentProviderConnection conn = app.conProviders.get(i);
14726                conn.provider.connections.remove(conn);
14727            }
14728            app.conProviders.clear();
14729        }
14730
14731        // At this point there may be remaining entries in mLaunchingProviders
14732        // where we were the only one waiting, so they are no longer of use.
14733        // Look for these and clean up if found.
14734        // XXX Commented out for now.  Trying to figure out a way to reproduce
14735        // the actual situation to identify what is actually going on.
14736        if (false) {
14737            for (int i=0; i<mLaunchingProviders.size(); i++) {
14738                ContentProviderRecord cpr = (ContentProviderRecord)
14739                        mLaunchingProviders.get(i);
14740                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14741                    synchronized (cpr) {
14742                        cpr.launchingApp = null;
14743                        cpr.notifyAll();
14744                    }
14745                }
14746            }
14747        }
14748
14749        skipCurrentReceiverLocked(app);
14750
14751        // Unregister any receivers.
14752        for (int i=app.receivers.size()-1; i>=0; i--) {
14753            removeReceiverLocked(app.receivers.valueAt(i));
14754        }
14755        app.receivers.clear();
14756
14757        // If the app is undergoing backup, tell the backup manager about it
14758        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14759            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14760                    + mBackupTarget.appInfo + " died during backup");
14761            try {
14762                IBackupManager bm = IBackupManager.Stub.asInterface(
14763                        ServiceManager.getService(Context.BACKUP_SERVICE));
14764                bm.agentDisconnected(app.info.packageName);
14765            } catch (RemoteException e) {
14766                // can't happen; backup manager is local
14767            }
14768        }
14769
14770        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14771            ProcessChangeItem item = mPendingProcessChanges.get(i);
14772            if (item.pid == app.pid) {
14773                mPendingProcessChanges.remove(i);
14774                mAvailProcessChanges.add(item);
14775            }
14776        }
14777        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14778
14779        // If the caller is restarting this app, then leave it in its
14780        // current lists and let the caller take care of it.
14781        if (restarting) {
14782            return false;
14783        }
14784
14785        if (!app.persistent || app.isolated) {
14786            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14787                    "Removing non-persistent process during cleanup: " + app);
14788            mProcessNames.remove(app.processName, app.uid);
14789            mIsolatedProcesses.remove(app.uid);
14790            if (mHeavyWeightProcess == app) {
14791                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14792                        mHeavyWeightProcess.userId, 0));
14793                mHeavyWeightProcess = null;
14794            }
14795        } else if (!app.removed) {
14796            // This app is persistent, so we need to keep its record around.
14797            // If it is not already on the pending app list, add it there
14798            // and start a new process for it.
14799            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14800                mPersistentStartingProcesses.add(app);
14801                restart = true;
14802            }
14803        }
14804        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14805                "Clean-up removing on hold: " + app);
14806        mProcessesOnHold.remove(app);
14807
14808        if (app == mHomeProcess) {
14809            mHomeProcess = null;
14810        }
14811        if (app == mPreviousProcess) {
14812            mPreviousProcess = null;
14813        }
14814
14815        if (restart && !app.isolated) {
14816            // We have components that still need to be running in the
14817            // process, so re-launch it.
14818            if (index < 0) {
14819                ProcessList.remove(app.pid);
14820            }
14821            mProcessNames.put(app.processName, app.uid, app);
14822            startProcessLocked(app, "restart", app.processName);
14823            return true;
14824        } else if (app.pid > 0 && app.pid != MY_PID) {
14825            // Goodbye!
14826            boolean removed;
14827            synchronized (mPidsSelfLocked) {
14828                mPidsSelfLocked.remove(app.pid);
14829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14830            }
14831            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14832            if (app.isolated) {
14833                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14834            }
14835            app.setPid(0);
14836        }
14837        return false;
14838    }
14839
14840    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14841        // Look through the content providers we are waiting to have launched,
14842        // and if any run in this process then either schedule a restart of
14843        // the process or kill the client waiting for it if this process has
14844        // gone bad.
14845        int NL = mLaunchingProviders.size();
14846        boolean restart = false;
14847        for (int i=0; i<NL; i++) {
14848            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14849            if (cpr.launchingApp == app) {
14850                if (!alwaysBad && !app.bad) {
14851                    restart = true;
14852                } else {
14853                    removeDyingProviderLocked(app, cpr, true);
14854                    // cpr should have been removed from mLaunchingProviders
14855                    NL = mLaunchingProviders.size();
14856                    i--;
14857                }
14858            }
14859        }
14860        return restart;
14861    }
14862
14863    // =========================================================
14864    // SERVICES
14865    // =========================================================
14866
14867    @Override
14868    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14869            int flags) {
14870        enforceNotIsolatedCaller("getServices");
14871        synchronized (this) {
14872            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14873        }
14874    }
14875
14876    @Override
14877    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14878        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14879        synchronized (this) {
14880            return mServices.getRunningServiceControlPanelLocked(name);
14881        }
14882    }
14883
14884    @Override
14885    public ComponentName startService(IApplicationThread caller, Intent service,
14886            String resolvedType, int userId) {
14887        enforceNotIsolatedCaller("startService");
14888        // Refuse possible leaked file descriptors
14889        if (service != null && service.hasFileDescriptors() == true) {
14890            throw new IllegalArgumentException("File descriptors passed in Intent");
14891        }
14892
14893        if (DEBUG_SERVICE)
14894            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14895        synchronized(this) {
14896            final int callingPid = Binder.getCallingPid();
14897            final int callingUid = Binder.getCallingUid();
14898            final long origId = Binder.clearCallingIdentity();
14899            ComponentName res = mServices.startServiceLocked(caller, service,
14900                    resolvedType, callingPid, callingUid, userId);
14901            Binder.restoreCallingIdentity(origId);
14902            return res;
14903        }
14904    }
14905
14906    ComponentName startServiceInPackage(int uid,
14907            Intent service, String resolvedType, int userId) {
14908        synchronized(this) {
14909            if (DEBUG_SERVICE)
14910                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14911            final long origId = Binder.clearCallingIdentity();
14912            ComponentName res = mServices.startServiceLocked(null, service,
14913                    resolvedType, -1, uid, userId);
14914            Binder.restoreCallingIdentity(origId);
14915            return res;
14916        }
14917    }
14918
14919    @Override
14920    public int stopService(IApplicationThread caller, Intent service,
14921            String resolvedType, int userId) {
14922        enforceNotIsolatedCaller("stopService");
14923        // Refuse possible leaked file descriptors
14924        if (service != null && service.hasFileDescriptors() == true) {
14925            throw new IllegalArgumentException("File descriptors passed in Intent");
14926        }
14927
14928        synchronized(this) {
14929            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14930        }
14931    }
14932
14933    @Override
14934    public IBinder peekService(Intent service, String resolvedType) {
14935        enforceNotIsolatedCaller("peekService");
14936        // Refuse possible leaked file descriptors
14937        if (service != null && service.hasFileDescriptors() == true) {
14938            throw new IllegalArgumentException("File descriptors passed in Intent");
14939        }
14940        synchronized(this) {
14941            return mServices.peekServiceLocked(service, resolvedType);
14942        }
14943    }
14944
14945    @Override
14946    public boolean stopServiceToken(ComponentName className, IBinder token,
14947            int startId) {
14948        synchronized(this) {
14949            return mServices.stopServiceTokenLocked(className, token, startId);
14950        }
14951    }
14952
14953    @Override
14954    public void setServiceForeground(ComponentName className, IBinder token,
14955            int id, Notification notification, boolean removeNotification) {
14956        synchronized(this) {
14957            mServices.setServiceForegroundLocked(className, token, id, notification,
14958                    removeNotification);
14959        }
14960    }
14961
14962    @Override
14963    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14964            boolean requireFull, String name, String callerPackage) {
14965        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14966                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14967    }
14968
14969    int unsafeConvertIncomingUser(int userId) {
14970        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14971                ? mCurrentUserId : userId;
14972    }
14973
14974    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14975            int allowMode, String name, String callerPackage) {
14976        final int callingUserId = UserHandle.getUserId(callingUid);
14977        if (callingUserId == userId) {
14978            return userId;
14979        }
14980
14981        // Note that we may be accessing mCurrentUserId outside of a lock...
14982        // shouldn't be a big deal, if this is being called outside
14983        // of a locked context there is intrinsically a race with
14984        // the value the caller will receive and someone else changing it.
14985        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14986        // we will switch to the calling user if access to the current user fails.
14987        int targetUserId = unsafeConvertIncomingUser(userId);
14988
14989        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14990            final boolean allow;
14991            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14992                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14993                // If the caller has this permission, they always pass go.  And collect $200.
14994                allow = true;
14995            } else if (allowMode == ALLOW_FULL_ONLY) {
14996                // We require full access, sucks to be you.
14997                allow = false;
14998            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14999                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15000                // If the caller does not have either permission, they are always doomed.
15001                allow = false;
15002            } else if (allowMode == ALLOW_NON_FULL) {
15003                // We are blanket allowing non-full access, you lucky caller!
15004                allow = true;
15005            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15006                // We may or may not allow this depending on whether the two users are
15007                // in the same profile.
15008                synchronized (mUserProfileGroupIdsSelfLocked) {
15009                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15010                            UserInfo.NO_PROFILE_GROUP_ID);
15011                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15012                            UserInfo.NO_PROFILE_GROUP_ID);
15013                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15014                            && callingProfile == targetProfile;
15015                }
15016            } else {
15017                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15018            }
15019            if (!allow) {
15020                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15021                    // In this case, they would like to just execute as their
15022                    // owner user instead of failing.
15023                    targetUserId = callingUserId;
15024                } else {
15025                    StringBuilder builder = new StringBuilder(128);
15026                    builder.append("Permission Denial: ");
15027                    builder.append(name);
15028                    if (callerPackage != null) {
15029                        builder.append(" from ");
15030                        builder.append(callerPackage);
15031                    }
15032                    builder.append(" asks to run as user ");
15033                    builder.append(userId);
15034                    builder.append(" but is calling from user ");
15035                    builder.append(UserHandle.getUserId(callingUid));
15036                    builder.append("; this requires ");
15037                    builder.append(INTERACT_ACROSS_USERS_FULL);
15038                    if (allowMode != ALLOW_FULL_ONLY) {
15039                        builder.append(" or ");
15040                        builder.append(INTERACT_ACROSS_USERS);
15041                    }
15042                    String msg = builder.toString();
15043                    Slog.w(TAG, msg);
15044                    throw new SecurityException(msg);
15045                }
15046            }
15047        }
15048        if (!allowAll && targetUserId < 0) {
15049            throw new IllegalArgumentException(
15050                    "Call does not support special user #" + targetUserId);
15051        }
15052        // Check shell permission
15053        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15054            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15055                    targetUserId)) {
15056                throw new SecurityException("Shell does not have permission to access user "
15057                        + targetUserId + "\n " + Debug.getCallers(3));
15058            }
15059        }
15060        return targetUserId;
15061    }
15062
15063    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15064            String className, int flags) {
15065        boolean result = false;
15066        // For apps that don't have pre-defined UIDs, check for permission
15067        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15068            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15069                if (ActivityManager.checkUidPermission(
15070                        INTERACT_ACROSS_USERS,
15071                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15072                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15073                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15074                            + " requests FLAG_SINGLE_USER, but app does not hold "
15075                            + INTERACT_ACROSS_USERS;
15076                    Slog.w(TAG, msg);
15077                    throw new SecurityException(msg);
15078                }
15079                // Permission passed
15080                result = true;
15081            }
15082        } else if ("system".equals(componentProcessName)) {
15083            result = true;
15084        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15085            // Phone app and persistent apps are allowed to export singleuser providers.
15086            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15087                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15088        }
15089        if (DEBUG_MU) {
15090            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15091                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15092        }
15093        return result;
15094    }
15095
15096    /**
15097     * Checks to see if the caller is in the same app as the singleton
15098     * component, or the component is in a special app. It allows special apps
15099     * to export singleton components but prevents exporting singleton
15100     * components for regular apps.
15101     */
15102    boolean isValidSingletonCall(int callingUid, int componentUid) {
15103        int componentAppId = UserHandle.getAppId(componentUid);
15104        return UserHandle.isSameApp(callingUid, componentUid)
15105                || componentAppId == Process.SYSTEM_UID
15106                || componentAppId == Process.PHONE_UID
15107                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15108                        == PackageManager.PERMISSION_GRANTED;
15109    }
15110
15111    public int bindService(IApplicationThread caller, IBinder token,
15112            Intent service, String resolvedType,
15113            IServiceConnection connection, int flags, int userId) {
15114        enforceNotIsolatedCaller("bindService");
15115
15116        // Refuse possible leaked file descriptors
15117        if (service != null && service.hasFileDescriptors() == true) {
15118            throw new IllegalArgumentException("File descriptors passed in Intent");
15119        }
15120
15121        synchronized(this) {
15122            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15123                    connection, flags, userId);
15124        }
15125    }
15126
15127    public boolean unbindService(IServiceConnection connection) {
15128        synchronized (this) {
15129            return mServices.unbindServiceLocked(connection);
15130        }
15131    }
15132
15133    public void publishService(IBinder token, Intent intent, IBinder service) {
15134        // Refuse possible leaked file descriptors
15135        if (intent != null && intent.hasFileDescriptors() == true) {
15136            throw new IllegalArgumentException("File descriptors passed in Intent");
15137        }
15138
15139        synchronized(this) {
15140            if (!(token instanceof ServiceRecord)) {
15141                throw new IllegalArgumentException("Invalid service token");
15142            }
15143            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15144        }
15145    }
15146
15147    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15148        // Refuse possible leaked file descriptors
15149        if (intent != null && intent.hasFileDescriptors() == true) {
15150            throw new IllegalArgumentException("File descriptors passed in Intent");
15151        }
15152
15153        synchronized(this) {
15154            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15155        }
15156    }
15157
15158    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15159        synchronized(this) {
15160            if (!(token instanceof ServiceRecord)) {
15161                throw new IllegalArgumentException("Invalid service token");
15162            }
15163            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15164        }
15165    }
15166
15167    // =========================================================
15168    // BACKUP AND RESTORE
15169    // =========================================================
15170
15171    // Cause the target app to be launched if necessary and its backup agent
15172    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15173    // activity manager to announce its creation.
15174    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15175        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15176        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15177
15178        synchronized(this) {
15179            // !!! TODO: currently no check here that we're already bound
15180            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15181            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15182            synchronized (stats) {
15183                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15184            }
15185
15186            // Backup agent is now in use, its package can't be stopped.
15187            try {
15188                AppGlobals.getPackageManager().setPackageStoppedState(
15189                        app.packageName, false, UserHandle.getUserId(app.uid));
15190            } catch (RemoteException e) {
15191            } catch (IllegalArgumentException e) {
15192                Slog.w(TAG, "Failed trying to unstop package "
15193                        + app.packageName + ": " + e);
15194            }
15195
15196            BackupRecord r = new BackupRecord(ss, app, backupMode);
15197            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15198                    ? new ComponentName(app.packageName, app.backupAgentName)
15199                    : new ComponentName("android", "FullBackupAgent");
15200            // startProcessLocked() returns existing proc's record if it's already running
15201            ProcessRecord proc = startProcessLocked(app.processName, app,
15202                    false, 0, "backup", hostingName, false, false, false);
15203            if (proc == null) {
15204                Slog.e(TAG, "Unable to start backup agent process " + r);
15205                return false;
15206            }
15207
15208            r.app = proc;
15209            mBackupTarget = r;
15210            mBackupAppName = app.packageName;
15211
15212            // Try not to kill the process during backup
15213            updateOomAdjLocked(proc);
15214
15215            // If the process is already attached, schedule the creation of the backup agent now.
15216            // If it is not yet live, this will be done when it attaches to the framework.
15217            if (proc.thread != null) {
15218                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15219                try {
15220                    proc.thread.scheduleCreateBackupAgent(app,
15221                            compatibilityInfoForPackageLocked(app), backupMode);
15222                } catch (RemoteException e) {
15223                    // Will time out on the backup manager side
15224                }
15225            } else {
15226                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15227            }
15228            // Invariants: at this point, the target app process exists and the application
15229            // is either already running or in the process of coming up.  mBackupTarget and
15230            // mBackupAppName describe the app, so that when it binds back to the AM we
15231            // know that it's scheduled for a backup-agent operation.
15232        }
15233
15234        return true;
15235    }
15236
15237    @Override
15238    public void clearPendingBackup() {
15239        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15240        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15241
15242        synchronized (this) {
15243            mBackupTarget = null;
15244            mBackupAppName = null;
15245        }
15246    }
15247
15248    // A backup agent has just come up
15249    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15250        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15251                + " = " + agent);
15252
15253        synchronized(this) {
15254            if (!agentPackageName.equals(mBackupAppName)) {
15255                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15256                return;
15257            }
15258        }
15259
15260        long oldIdent = Binder.clearCallingIdentity();
15261        try {
15262            IBackupManager bm = IBackupManager.Stub.asInterface(
15263                    ServiceManager.getService(Context.BACKUP_SERVICE));
15264            bm.agentConnected(agentPackageName, agent);
15265        } catch (RemoteException e) {
15266            // can't happen; the backup manager service is local
15267        } catch (Exception e) {
15268            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15269            e.printStackTrace();
15270        } finally {
15271            Binder.restoreCallingIdentity(oldIdent);
15272        }
15273    }
15274
15275    // done with this agent
15276    public void unbindBackupAgent(ApplicationInfo appInfo) {
15277        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15278        if (appInfo == null) {
15279            Slog.w(TAG, "unbind backup agent for null app");
15280            return;
15281        }
15282
15283        synchronized(this) {
15284            try {
15285                if (mBackupAppName == null) {
15286                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15287                    return;
15288                }
15289
15290                if (!mBackupAppName.equals(appInfo.packageName)) {
15291                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15292                    return;
15293                }
15294
15295                // Not backing this app up any more; reset its OOM adjustment
15296                final ProcessRecord proc = mBackupTarget.app;
15297                updateOomAdjLocked(proc);
15298
15299                // If the app crashed during backup, 'thread' will be null here
15300                if (proc.thread != null) {
15301                    try {
15302                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15303                                compatibilityInfoForPackageLocked(appInfo));
15304                    } catch (Exception e) {
15305                        Slog.e(TAG, "Exception when unbinding backup agent:");
15306                        e.printStackTrace();
15307                    }
15308                }
15309            } finally {
15310                mBackupTarget = null;
15311                mBackupAppName = null;
15312            }
15313        }
15314    }
15315    // =========================================================
15316    // BROADCASTS
15317    // =========================================================
15318
15319    private final List getStickiesLocked(String action, IntentFilter filter,
15320            List cur, int userId) {
15321        final ContentResolver resolver = mContext.getContentResolver();
15322        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15323        if (stickies == null) {
15324            return cur;
15325        }
15326        final ArrayList<Intent> list = stickies.get(action);
15327        if (list == null) {
15328            return cur;
15329        }
15330        int N = list.size();
15331        for (int i=0; i<N; i++) {
15332            Intent intent = list.get(i);
15333            if (filter.match(resolver, intent, true, TAG) >= 0) {
15334                if (cur == null) {
15335                    cur = new ArrayList<Intent>();
15336                }
15337                cur.add(intent);
15338            }
15339        }
15340        return cur;
15341    }
15342
15343    boolean isPendingBroadcastProcessLocked(int pid) {
15344        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15345                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15346    }
15347
15348    void skipPendingBroadcastLocked(int pid) {
15349            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15350            for (BroadcastQueue queue : mBroadcastQueues) {
15351                queue.skipPendingBroadcastLocked(pid);
15352            }
15353    }
15354
15355    // The app just attached; send any pending broadcasts that it should receive
15356    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15357        boolean didSomething = false;
15358        for (BroadcastQueue queue : mBroadcastQueues) {
15359            didSomething |= queue.sendPendingBroadcastsLocked(app);
15360        }
15361        return didSomething;
15362    }
15363
15364    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15365            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15366        enforceNotIsolatedCaller("registerReceiver");
15367        int callingUid;
15368        int callingPid;
15369        synchronized(this) {
15370            ProcessRecord callerApp = null;
15371            if (caller != null) {
15372                callerApp = getRecordForAppLocked(caller);
15373                if (callerApp == null) {
15374                    throw new SecurityException(
15375                            "Unable to find app for caller " + caller
15376                            + " (pid=" + Binder.getCallingPid()
15377                            + ") when registering receiver " + receiver);
15378                }
15379                if (callerApp.info.uid != Process.SYSTEM_UID &&
15380                        !callerApp.pkgList.containsKey(callerPackage) &&
15381                        !"android".equals(callerPackage)) {
15382                    throw new SecurityException("Given caller package " + callerPackage
15383                            + " is not running in process " + callerApp);
15384                }
15385                callingUid = callerApp.info.uid;
15386                callingPid = callerApp.pid;
15387            } else {
15388                callerPackage = null;
15389                callingUid = Binder.getCallingUid();
15390                callingPid = Binder.getCallingPid();
15391            }
15392
15393            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15394                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15395
15396            List allSticky = null;
15397
15398            // Look for any matching sticky broadcasts...
15399            Iterator actions = filter.actionsIterator();
15400            if (actions != null) {
15401                while (actions.hasNext()) {
15402                    String action = (String)actions.next();
15403                    allSticky = getStickiesLocked(action, filter, allSticky,
15404                            UserHandle.USER_ALL);
15405                    allSticky = getStickiesLocked(action, filter, allSticky,
15406                            UserHandle.getUserId(callingUid));
15407                }
15408            } else {
15409                allSticky = getStickiesLocked(null, filter, allSticky,
15410                        UserHandle.USER_ALL);
15411                allSticky = getStickiesLocked(null, filter, allSticky,
15412                        UserHandle.getUserId(callingUid));
15413            }
15414
15415            // The first sticky in the list is returned directly back to
15416            // the client.
15417            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15418
15419            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15420                    + ": " + sticky);
15421
15422            if (receiver == null) {
15423                return sticky;
15424            }
15425
15426            ReceiverList rl
15427                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15428            if (rl == null) {
15429                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15430                        userId, receiver);
15431                if (rl.app != null) {
15432                    rl.app.receivers.add(rl);
15433                } else {
15434                    try {
15435                        receiver.asBinder().linkToDeath(rl, 0);
15436                    } catch (RemoteException e) {
15437                        return sticky;
15438                    }
15439                    rl.linkedToDeath = true;
15440                }
15441                mRegisteredReceivers.put(receiver.asBinder(), rl);
15442            } else if (rl.uid != callingUid) {
15443                throw new IllegalArgumentException(
15444                        "Receiver requested to register for uid " + callingUid
15445                        + " was previously registered for uid " + rl.uid);
15446            } else if (rl.pid != callingPid) {
15447                throw new IllegalArgumentException(
15448                        "Receiver requested to register for pid " + callingPid
15449                        + " was previously registered for pid " + rl.pid);
15450            } else if (rl.userId != userId) {
15451                throw new IllegalArgumentException(
15452                        "Receiver requested to register for user " + userId
15453                        + " was previously registered for user " + rl.userId);
15454            }
15455            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15456                    permission, callingUid, userId);
15457            rl.add(bf);
15458            if (!bf.debugCheck()) {
15459                Slog.w(TAG, "==> For Dynamic broadast");
15460            }
15461            mReceiverResolver.addFilter(bf);
15462
15463            // Enqueue broadcasts for all existing stickies that match
15464            // this filter.
15465            if (allSticky != null) {
15466                ArrayList receivers = new ArrayList();
15467                receivers.add(bf);
15468
15469                int N = allSticky.size();
15470                for (int i=0; i<N; i++) {
15471                    Intent intent = (Intent)allSticky.get(i);
15472                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15473                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15474                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15475                            null, null, false, true, true, -1);
15476                    queue.enqueueParallelBroadcastLocked(r);
15477                    queue.scheduleBroadcastsLocked();
15478                }
15479            }
15480
15481            return sticky;
15482        }
15483    }
15484
15485    public void unregisterReceiver(IIntentReceiver receiver) {
15486        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15487
15488        final long origId = Binder.clearCallingIdentity();
15489        try {
15490            boolean doTrim = false;
15491
15492            synchronized(this) {
15493                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15494                if (rl != null) {
15495                    if (rl.curBroadcast != null) {
15496                        BroadcastRecord r = rl.curBroadcast;
15497                        final boolean doNext = finishReceiverLocked(
15498                                receiver.asBinder(), r.resultCode, r.resultData,
15499                                r.resultExtras, r.resultAbort);
15500                        if (doNext) {
15501                            doTrim = true;
15502                            r.queue.processNextBroadcast(false);
15503                        }
15504                    }
15505
15506                    if (rl.app != null) {
15507                        rl.app.receivers.remove(rl);
15508                    }
15509                    removeReceiverLocked(rl);
15510                    if (rl.linkedToDeath) {
15511                        rl.linkedToDeath = false;
15512                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15513                    }
15514                }
15515            }
15516
15517            // If we actually concluded any broadcasts, we might now be able
15518            // to trim the recipients' apps from our working set
15519            if (doTrim) {
15520                trimApplications();
15521                return;
15522            }
15523
15524        } finally {
15525            Binder.restoreCallingIdentity(origId);
15526        }
15527    }
15528
15529    void removeReceiverLocked(ReceiverList rl) {
15530        mRegisteredReceivers.remove(rl.receiver.asBinder());
15531        int N = rl.size();
15532        for (int i=0; i<N; i++) {
15533            mReceiverResolver.removeFilter(rl.get(i));
15534        }
15535    }
15536
15537    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15538        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15539            ProcessRecord r = mLruProcesses.get(i);
15540            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15541                try {
15542                    r.thread.dispatchPackageBroadcast(cmd, packages);
15543                } catch (RemoteException ex) {
15544                }
15545            }
15546        }
15547    }
15548
15549    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15550            int callingUid, int[] users) {
15551        List<ResolveInfo> receivers = null;
15552        try {
15553            HashSet<ComponentName> singleUserReceivers = null;
15554            boolean scannedFirstReceivers = false;
15555            for (int user : users) {
15556                // Skip users that have Shell restrictions
15557                if (callingUid == Process.SHELL_UID
15558                        && getUserManagerLocked().hasUserRestriction(
15559                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15560                    continue;
15561                }
15562                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15563                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15564                if (user != 0 && newReceivers != null) {
15565                    // If this is not the primary user, we need to check for
15566                    // any receivers that should be filtered out.
15567                    for (int i=0; i<newReceivers.size(); i++) {
15568                        ResolveInfo ri = newReceivers.get(i);
15569                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15570                            newReceivers.remove(i);
15571                            i--;
15572                        }
15573                    }
15574                }
15575                if (newReceivers != null && newReceivers.size() == 0) {
15576                    newReceivers = null;
15577                }
15578                if (receivers == null) {
15579                    receivers = newReceivers;
15580                } else if (newReceivers != null) {
15581                    // We need to concatenate the additional receivers
15582                    // found with what we have do far.  This would be easy,
15583                    // but we also need to de-dup any receivers that are
15584                    // singleUser.
15585                    if (!scannedFirstReceivers) {
15586                        // Collect any single user receivers we had already retrieved.
15587                        scannedFirstReceivers = true;
15588                        for (int i=0; i<receivers.size(); i++) {
15589                            ResolveInfo ri = receivers.get(i);
15590                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15591                                ComponentName cn = new ComponentName(
15592                                        ri.activityInfo.packageName, ri.activityInfo.name);
15593                                if (singleUserReceivers == null) {
15594                                    singleUserReceivers = new HashSet<ComponentName>();
15595                                }
15596                                singleUserReceivers.add(cn);
15597                            }
15598                        }
15599                    }
15600                    // Add the new results to the existing results, tracking
15601                    // and de-dupping single user receivers.
15602                    for (int i=0; i<newReceivers.size(); i++) {
15603                        ResolveInfo ri = newReceivers.get(i);
15604                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15605                            ComponentName cn = new ComponentName(
15606                                    ri.activityInfo.packageName, ri.activityInfo.name);
15607                            if (singleUserReceivers == null) {
15608                                singleUserReceivers = new HashSet<ComponentName>();
15609                            }
15610                            if (!singleUserReceivers.contains(cn)) {
15611                                singleUserReceivers.add(cn);
15612                                receivers.add(ri);
15613                            }
15614                        } else {
15615                            receivers.add(ri);
15616                        }
15617                    }
15618                }
15619            }
15620        } catch (RemoteException ex) {
15621            // pm is in same process, this will never happen.
15622        }
15623        return receivers;
15624    }
15625
15626    private final int broadcastIntentLocked(ProcessRecord callerApp,
15627            String callerPackage, Intent intent, String resolvedType,
15628            IIntentReceiver resultTo, int resultCode, String resultData,
15629            Bundle map, String requiredPermission, int appOp,
15630            boolean ordered, boolean sticky, int callingPid, int callingUid,
15631            int userId) {
15632        intent = new Intent(intent);
15633
15634        // By default broadcasts do not go to stopped apps.
15635        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15636
15637        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15638            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15639            + " ordered=" + ordered + " userid=" + userId);
15640        if ((resultTo != null) && !ordered) {
15641            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15642        }
15643
15644        userId = handleIncomingUser(callingPid, callingUid, userId,
15645                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15646
15647        // Make sure that the user who is receiving this broadcast is started.
15648        // If not, we will just skip it.
15649
15650        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15651            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15652                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15653                Slog.w(TAG, "Skipping broadcast of " + intent
15654                        + ": user " + userId + " is stopped");
15655                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15656            }
15657        }
15658
15659        /*
15660         * Prevent non-system code (defined here to be non-persistent
15661         * processes) from sending protected broadcasts.
15662         */
15663        int callingAppId = UserHandle.getAppId(callingUid);
15664        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15665            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15666            || callingAppId == Process.NFC_UID || callingUid == 0) {
15667            // Always okay.
15668        } else if (callerApp == null || !callerApp.persistent) {
15669            try {
15670                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15671                        intent.getAction())) {
15672                    String msg = "Permission Denial: not allowed to send broadcast "
15673                            + intent.getAction() + " from pid="
15674                            + callingPid + ", uid=" + callingUid;
15675                    Slog.w(TAG, msg);
15676                    throw new SecurityException(msg);
15677                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15678                    // Special case for compatibility: we don't want apps to send this,
15679                    // but historically it has not been protected and apps may be using it
15680                    // to poke their own app widget.  So, instead of making it protected,
15681                    // just limit it to the caller.
15682                    if (callerApp == null) {
15683                        String msg = "Permission Denial: not allowed to send broadcast "
15684                                + intent.getAction() + " from unknown caller.";
15685                        Slog.w(TAG, msg);
15686                        throw new SecurityException(msg);
15687                    } else if (intent.getComponent() != null) {
15688                        // They are good enough to send to an explicit component...  verify
15689                        // it is being sent to the calling app.
15690                        if (!intent.getComponent().getPackageName().equals(
15691                                callerApp.info.packageName)) {
15692                            String msg = "Permission Denial: not allowed to send broadcast "
15693                                    + intent.getAction() + " to "
15694                                    + intent.getComponent().getPackageName() + " from "
15695                                    + callerApp.info.packageName;
15696                            Slog.w(TAG, msg);
15697                            throw new SecurityException(msg);
15698                        }
15699                    } else {
15700                        // Limit broadcast to their own package.
15701                        intent.setPackage(callerApp.info.packageName);
15702                    }
15703                }
15704            } catch (RemoteException e) {
15705                Slog.w(TAG, "Remote exception", e);
15706                return ActivityManager.BROADCAST_SUCCESS;
15707            }
15708        }
15709
15710        final String action = intent.getAction();
15711        if (action != null) {
15712            switch (action) {
15713                case Intent.ACTION_UID_REMOVED:
15714                case Intent.ACTION_PACKAGE_REMOVED:
15715                case Intent.ACTION_PACKAGE_CHANGED:
15716                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15717                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15718                    // Handle special intents: if this broadcast is from the package
15719                    // manager about a package being removed, we need to remove all of
15720                    // its activities from the history stack.
15721                    if (checkComponentPermission(
15722                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15723                            callingPid, callingUid, -1, true)
15724                            != PackageManager.PERMISSION_GRANTED) {
15725                        String msg = "Permission Denial: " + intent.getAction()
15726                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15727                                + ", uid=" + callingUid + ")"
15728                                + " requires "
15729                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15730                        Slog.w(TAG, msg);
15731                        throw new SecurityException(msg);
15732                    }
15733                    switch (action) {
15734                        case Intent.ACTION_UID_REMOVED:
15735                            final Bundle intentExtras = intent.getExtras();
15736                            final int uid = intentExtras != null
15737                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15738                            if (uid >= 0) {
15739                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15740                                synchronized (bs) {
15741                                    bs.removeUidStatsLocked(uid);
15742                                }
15743                                mAppOpsService.uidRemoved(uid);
15744                            }
15745                            break;
15746                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15747                            // If resources are unavailable just force stop all those packages
15748                            // and flush the attribute cache as well.
15749                            String list[] =
15750                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15751                            if (list != null && list.length > 0) {
15752                                for (int i = 0; i < list.length; i++) {
15753                                    forceStopPackageLocked(list[i], -1, false, true, true,
15754                                            false, false, userId, "storage unmount");
15755                                }
15756                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15757                                sendPackageBroadcastLocked(
15758                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15759                                        userId);
15760                            }
15761                            break;
15762                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15763                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15764                            break;
15765                        case Intent.ACTION_PACKAGE_REMOVED:
15766                        case Intent.ACTION_PACKAGE_CHANGED:
15767                            Uri data = intent.getData();
15768                            String ssp;
15769                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15770                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15771                                boolean fullUninstall = removed &&
15772                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15773                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15774                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15775                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15776                                            false, true, true, false, fullUninstall, userId,
15777                                            removed ? "pkg removed" : "pkg changed");
15778                                }
15779                                if (removed) {
15780                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15781                                            new String[] {ssp}, userId);
15782                                    if (fullUninstall) {
15783                                        mAppOpsService.packageRemoved(
15784                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15785
15786                                        // Remove all permissions granted from/to this package
15787                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15788
15789                                        removeTasksByPackageNameLocked(ssp, userId);
15790                                    }
15791                                } else {
15792                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15793                                }
15794                            }
15795                            break;
15796                    }
15797                    break;
15798                case Intent.ACTION_PACKAGE_ADDED:
15799                    // Special case for adding a package: by default turn on compatibility mode.
15800                    Uri data = intent.getData();
15801                    String ssp;
15802                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15803                        final boolean replacing =
15804                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15805                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15806
15807                        if (replacing) {
15808                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15809                        }
15810                    }
15811                    break;
15812                case Intent.ACTION_TIMEZONE_CHANGED:
15813                    // If this is the time zone changed action, queue up a message that will reset
15814                    // the timezone of all currently running processes. This message will get
15815                    // queued up before the broadcast happens.
15816                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15817                    break;
15818                case Intent.ACTION_TIME_CHANGED:
15819                    // If the user set the time, let all running processes know.
15820                    final int is24Hour =
15821                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15822                                    : 0;
15823                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15824                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15825                    synchronized (stats) {
15826                        stats.noteCurrentTimeChangedLocked();
15827                    }
15828                    break;
15829                case Intent.ACTION_CLEAR_DNS_CACHE:
15830                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15831                    break;
15832                case Proxy.PROXY_CHANGE_ACTION:
15833                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15834                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15835                    break;
15836            }
15837        }
15838
15839        // Add to the sticky list if requested.
15840        if (sticky) {
15841            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15842                    callingPid, callingUid)
15843                    != PackageManager.PERMISSION_GRANTED) {
15844                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15845                        + callingPid + ", uid=" + callingUid
15846                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15847                Slog.w(TAG, msg);
15848                throw new SecurityException(msg);
15849            }
15850            if (requiredPermission != null) {
15851                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15852                        + " and enforce permission " + requiredPermission);
15853                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15854            }
15855            if (intent.getComponent() != null) {
15856                throw new SecurityException(
15857                        "Sticky broadcasts can't target a specific component");
15858            }
15859            // We use userId directly here, since the "all" target is maintained
15860            // as a separate set of sticky broadcasts.
15861            if (userId != UserHandle.USER_ALL) {
15862                // But first, if this is not a broadcast to all users, then
15863                // make sure it doesn't conflict with an existing broadcast to
15864                // all users.
15865                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15866                        UserHandle.USER_ALL);
15867                if (stickies != null) {
15868                    ArrayList<Intent> list = stickies.get(intent.getAction());
15869                    if (list != null) {
15870                        int N = list.size();
15871                        int i;
15872                        for (i=0; i<N; i++) {
15873                            if (intent.filterEquals(list.get(i))) {
15874                                throw new IllegalArgumentException(
15875                                        "Sticky broadcast " + intent + " for user "
15876                                        + userId + " conflicts with existing global broadcast");
15877                            }
15878                        }
15879                    }
15880                }
15881            }
15882            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15883            if (stickies == null) {
15884                stickies = new ArrayMap<String, ArrayList<Intent>>();
15885                mStickyBroadcasts.put(userId, stickies);
15886            }
15887            ArrayList<Intent> list = stickies.get(intent.getAction());
15888            if (list == null) {
15889                list = new ArrayList<Intent>();
15890                stickies.put(intent.getAction(), list);
15891            }
15892            int N = list.size();
15893            int i;
15894            for (i=0; i<N; i++) {
15895                if (intent.filterEquals(list.get(i))) {
15896                    // This sticky already exists, replace it.
15897                    list.set(i, new Intent(intent));
15898                    break;
15899                }
15900            }
15901            if (i >= N) {
15902                list.add(new Intent(intent));
15903            }
15904        }
15905
15906        int[] users;
15907        if (userId == UserHandle.USER_ALL) {
15908            // Caller wants broadcast to go to all started users.
15909            users = mStartedUserArray;
15910        } else {
15911            // Caller wants broadcast to go to one specific user.
15912            users = new int[] {userId};
15913        }
15914
15915        // Figure out who all will receive this broadcast.
15916        List receivers = null;
15917        List<BroadcastFilter> registeredReceivers = null;
15918        // Need to resolve the intent to interested receivers...
15919        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15920                 == 0) {
15921            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15922        }
15923        if (intent.getComponent() == null) {
15924            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15925                // Query one target user at a time, excluding shell-restricted users
15926                UserManagerService ums = getUserManagerLocked();
15927                for (int i = 0; i < users.length; i++) {
15928                    if (ums.hasUserRestriction(
15929                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15930                        continue;
15931                    }
15932                    List<BroadcastFilter> registeredReceiversForUser =
15933                            mReceiverResolver.queryIntent(intent,
15934                                    resolvedType, false, users[i]);
15935                    if (registeredReceivers == null) {
15936                        registeredReceivers = registeredReceiversForUser;
15937                    } else if (registeredReceiversForUser != null) {
15938                        registeredReceivers.addAll(registeredReceiversForUser);
15939                    }
15940                }
15941            } else {
15942                registeredReceivers = mReceiverResolver.queryIntent(intent,
15943                        resolvedType, false, userId);
15944            }
15945        }
15946
15947        final boolean replacePending =
15948                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15949
15950        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15951                + " replacePending=" + replacePending);
15952
15953        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15954        if (!ordered && NR > 0) {
15955            // If we are not serializing this broadcast, then send the
15956            // registered receivers separately so they don't wait for the
15957            // components to be launched.
15958            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15959            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15960                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15961                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15962                    ordered, sticky, false, userId);
15963            if (DEBUG_BROADCAST) Slog.v(
15964                    TAG, "Enqueueing parallel broadcast " + r);
15965            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15966            if (!replaced) {
15967                queue.enqueueParallelBroadcastLocked(r);
15968                queue.scheduleBroadcastsLocked();
15969            }
15970            registeredReceivers = null;
15971            NR = 0;
15972        }
15973
15974        // Merge into one list.
15975        int ir = 0;
15976        if (receivers != null) {
15977            // A special case for PACKAGE_ADDED: do not allow the package
15978            // being added to see this broadcast.  This prevents them from
15979            // using this as a back door to get run as soon as they are
15980            // installed.  Maybe in the future we want to have a special install
15981            // broadcast or such for apps, but we'd like to deliberately make
15982            // this decision.
15983            String skipPackages[] = null;
15984            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15985                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15986                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15987                Uri data = intent.getData();
15988                if (data != null) {
15989                    String pkgName = data.getSchemeSpecificPart();
15990                    if (pkgName != null) {
15991                        skipPackages = new String[] { pkgName };
15992                    }
15993                }
15994            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15995                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15996            }
15997            if (skipPackages != null && (skipPackages.length > 0)) {
15998                for (String skipPackage : skipPackages) {
15999                    if (skipPackage != null) {
16000                        int NT = receivers.size();
16001                        for (int it=0; it<NT; it++) {
16002                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16003                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16004                                receivers.remove(it);
16005                                it--;
16006                                NT--;
16007                            }
16008                        }
16009                    }
16010                }
16011            }
16012
16013            int NT = receivers != null ? receivers.size() : 0;
16014            int it = 0;
16015            ResolveInfo curt = null;
16016            BroadcastFilter curr = null;
16017            while (it < NT && ir < NR) {
16018                if (curt == null) {
16019                    curt = (ResolveInfo)receivers.get(it);
16020                }
16021                if (curr == null) {
16022                    curr = registeredReceivers.get(ir);
16023                }
16024                if (curr.getPriority() >= curt.priority) {
16025                    // Insert this broadcast record into the final list.
16026                    receivers.add(it, curr);
16027                    ir++;
16028                    curr = null;
16029                    it++;
16030                    NT++;
16031                } else {
16032                    // Skip to the next ResolveInfo in the final list.
16033                    it++;
16034                    curt = null;
16035                }
16036            }
16037        }
16038        while (ir < NR) {
16039            if (receivers == null) {
16040                receivers = new ArrayList();
16041            }
16042            receivers.add(registeredReceivers.get(ir));
16043            ir++;
16044        }
16045
16046        if ((receivers != null && receivers.size() > 0)
16047                || resultTo != null) {
16048            BroadcastQueue queue = broadcastQueueForIntent(intent);
16049            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16050                    callerPackage, callingPid, callingUid, resolvedType,
16051                    requiredPermission, appOp, receivers, resultTo, resultCode,
16052                    resultData, map, ordered, sticky, false, userId);
16053            if (DEBUG_BROADCAST) Slog.v(
16054                    TAG, "Enqueueing ordered broadcast " + r
16055                    + ": prev had " + queue.mOrderedBroadcasts.size());
16056            if (DEBUG_BROADCAST) {
16057                int seq = r.intent.getIntExtra("seq", -1);
16058                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16059            }
16060            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16061            if (!replaced) {
16062                queue.enqueueOrderedBroadcastLocked(r);
16063                queue.scheduleBroadcastsLocked();
16064            }
16065        }
16066
16067        return ActivityManager.BROADCAST_SUCCESS;
16068    }
16069
16070    final Intent verifyBroadcastLocked(Intent intent) {
16071        // Refuse possible leaked file descriptors
16072        if (intent != null && intent.hasFileDescriptors() == true) {
16073            throw new IllegalArgumentException("File descriptors passed in Intent");
16074        }
16075
16076        int flags = intent.getFlags();
16077
16078        if (!mProcessesReady) {
16079            // if the caller really truly claims to know what they're doing, go
16080            // ahead and allow the broadcast without launching any receivers
16081            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16082                intent = new Intent(intent);
16083                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16084            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16085                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16086                        + " before boot completion");
16087                throw new IllegalStateException("Cannot broadcast before boot completed");
16088            }
16089        }
16090
16091        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16092            throw new IllegalArgumentException(
16093                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16094        }
16095
16096        return intent;
16097    }
16098
16099    public final int broadcastIntent(IApplicationThread caller,
16100            Intent intent, String resolvedType, IIntentReceiver resultTo,
16101            int resultCode, String resultData, Bundle map,
16102            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16103        enforceNotIsolatedCaller("broadcastIntent");
16104        synchronized(this) {
16105            intent = verifyBroadcastLocked(intent);
16106
16107            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16108            final int callingPid = Binder.getCallingPid();
16109            final int callingUid = Binder.getCallingUid();
16110            final long origId = Binder.clearCallingIdentity();
16111            int res = broadcastIntentLocked(callerApp,
16112                    callerApp != null ? callerApp.info.packageName : null,
16113                    intent, resolvedType, resultTo,
16114                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16115                    callingPid, callingUid, userId);
16116            Binder.restoreCallingIdentity(origId);
16117            return res;
16118        }
16119    }
16120
16121    int broadcastIntentInPackage(String packageName, int uid,
16122            Intent intent, String resolvedType, IIntentReceiver resultTo,
16123            int resultCode, String resultData, Bundle map,
16124            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16125        synchronized(this) {
16126            intent = verifyBroadcastLocked(intent);
16127
16128            final long origId = Binder.clearCallingIdentity();
16129            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16130                    resultTo, resultCode, resultData, map, requiredPermission,
16131                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16132            Binder.restoreCallingIdentity(origId);
16133            return res;
16134        }
16135    }
16136
16137    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16138        // Refuse possible leaked file descriptors
16139        if (intent != null && intent.hasFileDescriptors() == true) {
16140            throw new IllegalArgumentException("File descriptors passed in Intent");
16141        }
16142
16143        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16144                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16145
16146        synchronized(this) {
16147            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16148                    != PackageManager.PERMISSION_GRANTED) {
16149                String msg = "Permission Denial: unbroadcastIntent() from pid="
16150                        + Binder.getCallingPid()
16151                        + ", uid=" + Binder.getCallingUid()
16152                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16153                Slog.w(TAG, msg);
16154                throw new SecurityException(msg);
16155            }
16156            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16157            if (stickies != null) {
16158                ArrayList<Intent> list = stickies.get(intent.getAction());
16159                if (list != null) {
16160                    int N = list.size();
16161                    int i;
16162                    for (i=0; i<N; i++) {
16163                        if (intent.filterEquals(list.get(i))) {
16164                            list.remove(i);
16165                            break;
16166                        }
16167                    }
16168                    if (list.size() <= 0) {
16169                        stickies.remove(intent.getAction());
16170                    }
16171                }
16172                if (stickies.size() <= 0) {
16173                    mStickyBroadcasts.remove(userId);
16174                }
16175            }
16176        }
16177    }
16178
16179    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16180            String resultData, Bundle resultExtras, boolean resultAbort) {
16181        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16182        if (r == null) {
16183            Slog.w(TAG, "finishReceiver called but not found on queue");
16184            return false;
16185        }
16186
16187        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16188    }
16189
16190    void backgroundServicesFinishedLocked(int userId) {
16191        for (BroadcastQueue queue : mBroadcastQueues) {
16192            queue.backgroundServicesFinishedLocked(userId);
16193        }
16194    }
16195
16196    public void finishReceiver(IBinder who, int resultCode, String resultData,
16197            Bundle resultExtras, boolean resultAbort) {
16198        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16199
16200        // Refuse possible leaked file descriptors
16201        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16202            throw new IllegalArgumentException("File descriptors passed in Bundle");
16203        }
16204
16205        final long origId = Binder.clearCallingIdentity();
16206        try {
16207            boolean doNext = false;
16208            BroadcastRecord r;
16209
16210            synchronized(this) {
16211                r = broadcastRecordForReceiverLocked(who);
16212                if (r != null) {
16213                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16214                        resultData, resultExtras, resultAbort, true);
16215                }
16216            }
16217
16218            if (doNext) {
16219                r.queue.processNextBroadcast(false);
16220            }
16221            trimApplications();
16222        } finally {
16223            Binder.restoreCallingIdentity(origId);
16224        }
16225    }
16226
16227    // =========================================================
16228    // INSTRUMENTATION
16229    // =========================================================
16230
16231    public boolean startInstrumentation(ComponentName className,
16232            String profileFile, int flags, Bundle arguments,
16233            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16234            int userId, String abiOverride) {
16235        enforceNotIsolatedCaller("startInstrumentation");
16236        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16237                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16238        // Refuse possible leaked file descriptors
16239        if (arguments != null && arguments.hasFileDescriptors()) {
16240            throw new IllegalArgumentException("File descriptors passed in Bundle");
16241        }
16242
16243        synchronized(this) {
16244            InstrumentationInfo ii = null;
16245            ApplicationInfo ai = null;
16246            try {
16247                ii = mContext.getPackageManager().getInstrumentationInfo(
16248                    className, STOCK_PM_FLAGS);
16249                ai = AppGlobals.getPackageManager().getApplicationInfo(
16250                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16251            } catch (PackageManager.NameNotFoundException e) {
16252            } catch (RemoteException e) {
16253            }
16254            if (ii == null) {
16255                reportStartInstrumentationFailure(watcher, className,
16256                        "Unable to find instrumentation info for: " + className);
16257                return false;
16258            }
16259            if (ai == null) {
16260                reportStartInstrumentationFailure(watcher, className,
16261                        "Unable to find instrumentation target package: " + ii.targetPackage);
16262                return false;
16263            }
16264
16265            int match = mContext.getPackageManager().checkSignatures(
16266                    ii.targetPackage, ii.packageName);
16267            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16268                String msg = "Permission Denial: starting instrumentation "
16269                        + className + " from pid="
16270                        + Binder.getCallingPid()
16271                        + ", uid=" + Binder.getCallingPid()
16272                        + " not allowed because package " + ii.packageName
16273                        + " does not have a signature matching the target "
16274                        + ii.targetPackage;
16275                reportStartInstrumentationFailure(watcher, className, msg);
16276                throw new SecurityException(msg);
16277            }
16278
16279            final long origId = Binder.clearCallingIdentity();
16280            // Instrumentation can kill and relaunch even persistent processes
16281            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16282                    "start instr");
16283            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16284            app.instrumentationClass = className;
16285            app.instrumentationInfo = ai;
16286            app.instrumentationProfileFile = profileFile;
16287            app.instrumentationArguments = arguments;
16288            app.instrumentationWatcher = watcher;
16289            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16290            app.instrumentationResultClass = className;
16291            Binder.restoreCallingIdentity(origId);
16292        }
16293
16294        return true;
16295    }
16296
16297    /**
16298     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16299     * error to the logs, but if somebody is watching, send the report there too.  This enables
16300     * the "am" command to report errors with more information.
16301     *
16302     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16303     * @param cn The component name of the instrumentation.
16304     * @param report The error report.
16305     */
16306    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16307            ComponentName cn, String report) {
16308        Slog.w(TAG, report);
16309        try {
16310            if (watcher != null) {
16311                Bundle results = new Bundle();
16312                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16313                results.putString("Error", report);
16314                watcher.instrumentationStatus(cn, -1, results);
16315            }
16316        } catch (RemoteException e) {
16317            Slog.w(TAG, e);
16318        }
16319    }
16320
16321    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16322        if (app.instrumentationWatcher != null) {
16323            try {
16324                // NOTE:  IInstrumentationWatcher *must* be oneway here
16325                app.instrumentationWatcher.instrumentationFinished(
16326                    app.instrumentationClass,
16327                    resultCode,
16328                    results);
16329            } catch (RemoteException e) {
16330            }
16331        }
16332        if (app.instrumentationUiAutomationConnection != null) {
16333            try {
16334                app.instrumentationUiAutomationConnection.shutdown();
16335            } catch (RemoteException re) {
16336                /* ignore */
16337            }
16338            // Only a UiAutomation can set this flag and now that
16339            // it is finished we make sure it is reset to its default.
16340            mUserIsMonkey = false;
16341        }
16342        app.instrumentationWatcher = null;
16343        app.instrumentationUiAutomationConnection = null;
16344        app.instrumentationClass = null;
16345        app.instrumentationInfo = null;
16346        app.instrumentationProfileFile = null;
16347        app.instrumentationArguments = null;
16348
16349        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16350                "finished inst");
16351    }
16352
16353    public void finishInstrumentation(IApplicationThread target,
16354            int resultCode, Bundle results) {
16355        int userId = UserHandle.getCallingUserId();
16356        // Refuse possible leaked file descriptors
16357        if (results != null && results.hasFileDescriptors()) {
16358            throw new IllegalArgumentException("File descriptors passed in Intent");
16359        }
16360
16361        synchronized(this) {
16362            ProcessRecord app = getRecordForAppLocked(target);
16363            if (app == null) {
16364                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16365                return;
16366            }
16367            final long origId = Binder.clearCallingIdentity();
16368            finishInstrumentationLocked(app, resultCode, results);
16369            Binder.restoreCallingIdentity(origId);
16370        }
16371    }
16372
16373    // =========================================================
16374    // CONFIGURATION
16375    // =========================================================
16376
16377    public ConfigurationInfo getDeviceConfigurationInfo() {
16378        ConfigurationInfo config = new ConfigurationInfo();
16379        synchronized (this) {
16380            config.reqTouchScreen = mConfiguration.touchscreen;
16381            config.reqKeyboardType = mConfiguration.keyboard;
16382            config.reqNavigation = mConfiguration.navigation;
16383            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16384                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16385                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16386            }
16387            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16388                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16389                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16390            }
16391            config.reqGlEsVersion = GL_ES_VERSION;
16392        }
16393        return config;
16394    }
16395
16396    ActivityStack getFocusedStack() {
16397        return mStackSupervisor.getFocusedStack();
16398    }
16399
16400    public Configuration getConfiguration() {
16401        Configuration ci;
16402        synchronized(this) {
16403            ci = new Configuration(mConfiguration);
16404        }
16405        return ci;
16406    }
16407
16408    public void updatePersistentConfiguration(Configuration values) {
16409        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16410                "updateConfiguration()");
16411        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16412                "updateConfiguration()");
16413        if (values == null) {
16414            throw new NullPointerException("Configuration must not be null");
16415        }
16416
16417        synchronized(this) {
16418            final long origId = Binder.clearCallingIdentity();
16419            updateConfigurationLocked(values, null, true, false);
16420            Binder.restoreCallingIdentity(origId);
16421        }
16422    }
16423
16424    public void updateConfiguration(Configuration values) {
16425        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16426                "updateConfiguration()");
16427
16428        synchronized(this) {
16429            if (values == null && mWindowManager != null) {
16430                // sentinel: fetch the current configuration from the window manager
16431                values = mWindowManager.computeNewConfiguration();
16432            }
16433
16434            if (mWindowManager != null) {
16435                mProcessList.applyDisplaySize(mWindowManager);
16436            }
16437
16438            final long origId = Binder.clearCallingIdentity();
16439            if (values != null) {
16440                Settings.System.clearConfiguration(values);
16441            }
16442            updateConfigurationLocked(values, null, false, false);
16443            Binder.restoreCallingIdentity(origId);
16444        }
16445    }
16446
16447    /**
16448     * Do either or both things: (1) change the current configuration, and (2)
16449     * make sure the given activity is running with the (now) current
16450     * configuration.  Returns true if the activity has been left running, or
16451     * false if <var>starting</var> is being destroyed to match the new
16452     * configuration.
16453     * @param persistent TODO
16454     */
16455    boolean updateConfigurationLocked(Configuration values,
16456            ActivityRecord starting, boolean persistent, boolean initLocale) {
16457        int changes = 0;
16458
16459        if (values != null) {
16460            Configuration newConfig = new Configuration(mConfiguration);
16461            changes = newConfig.updateFrom(values);
16462            if (changes != 0) {
16463                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16464                    Slog.i(TAG, "Updating configuration to: " + values);
16465                }
16466
16467                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16468
16469                if (values.locale != null && !initLocale) {
16470                    saveLocaleLocked(values.locale,
16471                                     !values.locale.equals(mConfiguration.locale),
16472                                     values.userSetLocale);
16473                }
16474
16475                mConfigurationSeq++;
16476                if (mConfigurationSeq <= 0) {
16477                    mConfigurationSeq = 1;
16478                }
16479                newConfig.seq = mConfigurationSeq;
16480                mConfiguration = newConfig;
16481                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16482                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16483                //mUsageStatsService.noteStartConfig(newConfig);
16484
16485                final Configuration configCopy = new Configuration(mConfiguration);
16486
16487                // TODO: If our config changes, should we auto dismiss any currently
16488                // showing dialogs?
16489                mShowDialogs = shouldShowDialogs(newConfig);
16490
16491                AttributeCache ac = AttributeCache.instance();
16492                if (ac != null) {
16493                    ac.updateConfiguration(configCopy);
16494                }
16495
16496                // Make sure all resources in our process are updated
16497                // right now, so that anyone who is going to retrieve
16498                // resource values after we return will be sure to get
16499                // the new ones.  This is especially important during
16500                // boot, where the first config change needs to guarantee
16501                // all resources have that config before following boot
16502                // code is executed.
16503                mSystemThread.applyConfigurationToResources(configCopy);
16504
16505                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16506                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16507                    msg.obj = new Configuration(configCopy);
16508                    mHandler.sendMessage(msg);
16509                }
16510
16511                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16512                    ProcessRecord app = mLruProcesses.get(i);
16513                    try {
16514                        if (app.thread != null) {
16515                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16516                                    + app.processName + " new config " + mConfiguration);
16517                            app.thread.scheduleConfigurationChanged(configCopy);
16518                        }
16519                    } catch (Exception e) {
16520                    }
16521                }
16522                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16523                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16524                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16525                        | Intent.FLAG_RECEIVER_FOREGROUND);
16526                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16527                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16528                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16529                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16530                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16531                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16532                    broadcastIntentLocked(null, null, intent,
16533                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16534                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16535                }
16536            }
16537        }
16538
16539        boolean kept = true;
16540        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16541        // mainStack is null during startup.
16542        if (mainStack != null) {
16543            if (changes != 0 && starting == null) {
16544                // If the configuration changed, and the caller is not already
16545                // in the process of starting an activity, then find the top
16546                // activity to check if its configuration needs to change.
16547                starting = mainStack.topRunningActivityLocked(null);
16548            }
16549
16550            if (starting != null) {
16551                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16552                // And we need to make sure at this point that all other activities
16553                // are made visible with the correct configuration.
16554                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16555            }
16556        }
16557
16558        if (values != null && mWindowManager != null) {
16559            mWindowManager.setNewConfiguration(mConfiguration);
16560        }
16561
16562        return kept;
16563    }
16564
16565    /**
16566     * Decide based on the configuration whether we should shouw the ANR,
16567     * crash, etc dialogs.  The idea is that if there is no affordnace to
16568     * press the on-screen buttons, we shouldn't show the dialog.
16569     *
16570     * A thought: SystemUI might also want to get told about this, the Power
16571     * dialog / global actions also might want different behaviors.
16572     */
16573    private static final boolean shouldShowDialogs(Configuration config) {
16574        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16575                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16576    }
16577
16578    /**
16579     * Save the locale.  You must be inside a synchronized (this) block.
16580     */
16581    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16582        if(isDiff) {
16583            SystemProperties.set("user.language", l.getLanguage());
16584            SystemProperties.set("user.region", l.getCountry());
16585        }
16586
16587        if(isPersist) {
16588            SystemProperties.set("persist.sys.language", l.getLanguage());
16589            SystemProperties.set("persist.sys.country", l.getCountry());
16590            SystemProperties.set("persist.sys.localevar", l.getVariant());
16591
16592            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16593        }
16594    }
16595
16596    @Override
16597    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16598        synchronized (this) {
16599            ActivityRecord srec = ActivityRecord.forToken(token);
16600            if (srec.task != null && srec.task.stack != null) {
16601                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16602            }
16603        }
16604        return false;
16605    }
16606
16607    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16608            Intent resultData) {
16609
16610        synchronized (this) {
16611            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16612            if (stack != null) {
16613                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16614            }
16615            return false;
16616        }
16617    }
16618
16619    public int getLaunchedFromUid(IBinder activityToken) {
16620        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16621        if (srec == null) {
16622            return -1;
16623        }
16624        return srec.launchedFromUid;
16625    }
16626
16627    public String getLaunchedFromPackage(IBinder activityToken) {
16628        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16629        if (srec == null) {
16630            return null;
16631        }
16632        return srec.launchedFromPackage;
16633    }
16634
16635    // =========================================================
16636    // LIFETIME MANAGEMENT
16637    // =========================================================
16638
16639    // Returns which broadcast queue the app is the current [or imminent] receiver
16640    // on, or 'null' if the app is not an active broadcast recipient.
16641    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16642        BroadcastRecord r = app.curReceiver;
16643        if (r != null) {
16644            return r.queue;
16645        }
16646
16647        // It's not the current receiver, but it might be starting up to become one
16648        synchronized (this) {
16649            for (BroadcastQueue queue : mBroadcastQueues) {
16650                r = queue.mPendingBroadcast;
16651                if (r != null && r.curApp == app) {
16652                    // found it; report which queue it's in
16653                    return queue;
16654                }
16655            }
16656        }
16657
16658        return null;
16659    }
16660
16661    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16662            boolean doingAll, long now) {
16663        if (mAdjSeq == app.adjSeq) {
16664            // This adjustment has already been computed.
16665            return app.curRawAdj;
16666        }
16667
16668        if (app.thread == null) {
16669            app.adjSeq = mAdjSeq;
16670            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16671            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16672            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16673        }
16674
16675        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16676        app.adjSource = null;
16677        app.adjTarget = null;
16678        app.empty = false;
16679        app.cached = false;
16680
16681        final int activitiesSize = app.activities.size();
16682
16683        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16684            // The max adjustment doesn't allow this app to be anything
16685            // below foreground, so it is not worth doing work for it.
16686            app.adjType = "fixed";
16687            app.adjSeq = mAdjSeq;
16688            app.curRawAdj = app.maxAdj;
16689            app.foregroundActivities = false;
16690            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16691            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16692            // System processes can do UI, and when they do we want to have
16693            // them trim their memory after the user leaves the UI.  To
16694            // facilitate this, here we need to determine whether or not it
16695            // is currently showing UI.
16696            app.systemNoUi = true;
16697            if (app == TOP_APP) {
16698                app.systemNoUi = false;
16699            } else if (activitiesSize > 0) {
16700                for (int j = 0; j < activitiesSize; j++) {
16701                    final ActivityRecord r = app.activities.get(j);
16702                    if (r.visible) {
16703                        app.systemNoUi = false;
16704                    }
16705                }
16706            }
16707            if (!app.systemNoUi) {
16708                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16709            }
16710            return (app.curAdj=app.maxAdj);
16711        }
16712
16713        app.systemNoUi = false;
16714
16715        // Determine the importance of the process, starting with most
16716        // important to least, and assign an appropriate OOM adjustment.
16717        int adj;
16718        int schedGroup;
16719        int procState;
16720        boolean foregroundActivities = false;
16721        BroadcastQueue queue;
16722        if (app == TOP_APP) {
16723            // The last app on the list is the foreground app.
16724            adj = ProcessList.FOREGROUND_APP_ADJ;
16725            schedGroup = Process.THREAD_GROUP_DEFAULT;
16726            app.adjType = "top-activity";
16727            foregroundActivities = true;
16728            procState = ActivityManager.PROCESS_STATE_TOP;
16729        } else if (app.instrumentationClass != null) {
16730            // Don't want to kill running instrumentation.
16731            adj = ProcessList.FOREGROUND_APP_ADJ;
16732            schedGroup = Process.THREAD_GROUP_DEFAULT;
16733            app.adjType = "instrumentation";
16734            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16735        } else if ((queue = isReceivingBroadcast(app)) != null) {
16736            // An app that is currently receiving a broadcast also
16737            // counts as being in the foreground for OOM killer purposes.
16738            // It's placed in a sched group based on the nature of the
16739            // broadcast as reflected by which queue it's active in.
16740            adj = ProcessList.FOREGROUND_APP_ADJ;
16741            schedGroup = (queue == mFgBroadcastQueue)
16742                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16743            app.adjType = "broadcast";
16744            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16745        } else if (app.executingServices.size() > 0) {
16746            // An app that is currently executing a service callback also
16747            // counts as being in the foreground.
16748            adj = ProcessList.FOREGROUND_APP_ADJ;
16749            schedGroup = app.execServicesFg ?
16750                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16751            app.adjType = "exec-service";
16752            procState = ActivityManager.PROCESS_STATE_SERVICE;
16753            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16754        } else {
16755            // As far as we know the process is empty.  We may change our mind later.
16756            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16757            // At this point we don't actually know the adjustment.  Use the cached adj
16758            // value that the caller wants us to.
16759            adj = cachedAdj;
16760            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16761            app.cached = true;
16762            app.empty = true;
16763            app.adjType = "cch-empty";
16764        }
16765
16766        // Examine all activities if not already foreground.
16767        if (!foregroundActivities && activitiesSize > 0) {
16768            for (int j = 0; j < activitiesSize; j++) {
16769                final ActivityRecord r = app.activities.get(j);
16770                if (r.app != app) {
16771                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16772                            + app + "?!?");
16773                    continue;
16774                }
16775                if (r.visible) {
16776                    // App has a visible activity; only upgrade adjustment.
16777                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16778                        adj = ProcessList.VISIBLE_APP_ADJ;
16779                        app.adjType = "visible";
16780                    }
16781                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16782                        procState = ActivityManager.PROCESS_STATE_TOP;
16783                    }
16784                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16785                    app.cached = false;
16786                    app.empty = false;
16787                    foregroundActivities = true;
16788                    break;
16789                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16790                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16791                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16792                        app.adjType = "pausing";
16793                    }
16794                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16795                        procState = ActivityManager.PROCESS_STATE_TOP;
16796                    }
16797                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16798                    app.cached = false;
16799                    app.empty = false;
16800                    foregroundActivities = true;
16801                } else if (r.state == ActivityState.STOPPING) {
16802                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16803                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16804                        app.adjType = "stopping";
16805                    }
16806                    // For the process state, we will at this point consider the
16807                    // process to be cached.  It will be cached either as an activity
16808                    // or empty depending on whether the activity is finishing.  We do
16809                    // this so that we can treat the process as cached for purposes of
16810                    // memory trimming (determing current memory level, trim command to
16811                    // send to process) since there can be an arbitrary number of stopping
16812                    // processes and they should soon all go into the cached state.
16813                    if (!r.finishing) {
16814                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16815                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16816                        }
16817                    }
16818                    app.cached = false;
16819                    app.empty = false;
16820                    foregroundActivities = true;
16821                } else {
16822                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16823                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16824                        app.adjType = "cch-act";
16825                    }
16826                }
16827            }
16828        }
16829
16830        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16831            if (app.foregroundServices) {
16832                // The user is aware of this app, so make it visible.
16833                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16834                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16835                app.cached = false;
16836                app.adjType = "fg-service";
16837                schedGroup = Process.THREAD_GROUP_DEFAULT;
16838            } else if (app.forcingToForeground != null) {
16839                // The user is aware of this app, so make it visible.
16840                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16841                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16842                app.cached = false;
16843                app.adjType = "force-fg";
16844                app.adjSource = app.forcingToForeground;
16845                schedGroup = Process.THREAD_GROUP_DEFAULT;
16846            }
16847        }
16848
16849        if (app == mHeavyWeightProcess) {
16850            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16851                // We don't want to kill the current heavy-weight process.
16852                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16853                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16854                app.cached = false;
16855                app.adjType = "heavy";
16856            }
16857            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16858                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16859            }
16860        }
16861
16862        if (app == mHomeProcess) {
16863            if (adj > ProcessList.HOME_APP_ADJ) {
16864                // This process is hosting what we currently consider to be the
16865                // home app, so we don't want to let it go into the background.
16866                adj = ProcessList.HOME_APP_ADJ;
16867                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16868                app.cached = false;
16869                app.adjType = "home";
16870            }
16871            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16872                procState = ActivityManager.PROCESS_STATE_HOME;
16873            }
16874        }
16875
16876        if (app == mPreviousProcess && app.activities.size() > 0) {
16877            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16878                // This was the previous process that showed UI to the user.
16879                // We want to try to keep it around more aggressively, to give
16880                // a good experience around switching between two apps.
16881                adj = ProcessList.PREVIOUS_APP_ADJ;
16882                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16883                app.cached = false;
16884                app.adjType = "previous";
16885            }
16886            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16887                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16888            }
16889        }
16890
16891        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16892                + " reason=" + app.adjType);
16893
16894        // By default, we use the computed adjustment.  It may be changed if
16895        // there are applications dependent on our services or providers, but
16896        // this gives us a baseline and makes sure we don't get into an
16897        // infinite recursion.
16898        app.adjSeq = mAdjSeq;
16899        app.curRawAdj = adj;
16900        app.hasStartedServices = false;
16901
16902        if (mBackupTarget != null && app == mBackupTarget.app) {
16903            // If possible we want to avoid killing apps while they're being backed up
16904            if (adj > ProcessList.BACKUP_APP_ADJ) {
16905                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16906                adj = ProcessList.BACKUP_APP_ADJ;
16907                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16908                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16909                }
16910                app.adjType = "backup";
16911                app.cached = false;
16912            }
16913            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16914                procState = ActivityManager.PROCESS_STATE_BACKUP;
16915            }
16916        }
16917
16918        boolean mayBeTop = false;
16919
16920        for (int is = app.services.size()-1;
16921                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16922                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16923                        || procState > ActivityManager.PROCESS_STATE_TOP);
16924                is--) {
16925            ServiceRecord s = app.services.valueAt(is);
16926            if (s.startRequested) {
16927                app.hasStartedServices = true;
16928                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16929                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16930                }
16931                if (app.hasShownUi && app != mHomeProcess) {
16932                    // If this process has shown some UI, let it immediately
16933                    // go to the LRU list because it may be pretty heavy with
16934                    // UI stuff.  We'll tag it with a label just to help
16935                    // debug and understand what is going on.
16936                    if (adj > ProcessList.SERVICE_ADJ) {
16937                        app.adjType = "cch-started-ui-services";
16938                    }
16939                } else {
16940                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16941                        // This service has seen some activity within
16942                        // recent memory, so we will keep its process ahead
16943                        // of the background processes.
16944                        if (adj > ProcessList.SERVICE_ADJ) {
16945                            adj = ProcessList.SERVICE_ADJ;
16946                            app.adjType = "started-services";
16947                            app.cached = false;
16948                        }
16949                    }
16950                    // If we have let the service slide into the background
16951                    // state, still have some text describing what it is doing
16952                    // even though the service no longer has an impact.
16953                    if (adj > ProcessList.SERVICE_ADJ) {
16954                        app.adjType = "cch-started-services";
16955                    }
16956                }
16957            }
16958            for (int conni = s.connections.size()-1;
16959                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16960                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16961                            || procState > ActivityManager.PROCESS_STATE_TOP);
16962                    conni--) {
16963                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16964                for (int i = 0;
16965                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16966                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16967                                || procState > ActivityManager.PROCESS_STATE_TOP);
16968                        i++) {
16969                    // XXX should compute this based on the max of
16970                    // all connected clients.
16971                    ConnectionRecord cr = clist.get(i);
16972                    if (cr.binding.client == app) {
16973                        // Binding to ourself is not interesting.
16974                        continue;
16975                    }
16976                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16977                        ProcessRecord client = cr.binding.client;
16978                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16979                                TOP_APP, doingAll, now);
16980                        int clientProcState = client.curProcState;
16981                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16982                            // If the other app is cached for any reason, for purposes here
16983                            // we are going to consider it empty.  The specific cached state
16984                            // doesn't propagate except under certain conditions.
16985                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16986                        }
16987                        String adjType = null;
16988                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16989                            // Not doing bind OOM management, so treat
16990                            // this guy more like a started service.
16991                            if (app.hasShownUi && app != mHomeProcess) {
16992                                // If this process has shown some UI, let it immediately
16993                                // go to the LRU list because it may be pretty heavy with
16994                                // UI stuff.  We'll tag it with a label just to help
16995                                // debug and understand what is going on.
16996                                if (adj > clientAdj) {
16997                                    adjType = "cch-bound-ui-services";
16998                                }
16999                                app.cached = false;
17000                                clientAdj = adj;
17001                                clientProcState = procState;
17002                            } else {
17003                                if (now >= (s.lastActivity
17004                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17005                                    // This service has not seen activity within
17006                                    // recent memory, so allow it to drop to the
17007                                    // LRU list if there is no other reason to keep
17008                                    // it around.  We'll also tag it with a label just
17009                                    // to help debug and undertand what is going on.
17010                                    if (adj > clientAdj) {
17011                                        adjType = "cch-bound-services";
17012                                    }
17013                                    clientAdj = adj;
17014                                }
17015                            }
17016                        }
17017                        if (adj > clientAdj) {
17018                            // If this process has recently shown UI, and
17019                            // the process that is binding to it is less
17020                            // important than being visible, then we don't
17021                            // care about the binding as much as we care
17022                            // about letting this process get into the LRU
17023                            // list to be killed and restarted if needed for
17024                            // memory.
17025                            if (app.hasShownUi && app != mHomeProcess
17026                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17027                                adjType = "cch-bound-ui-services";
17028                            } else {
17029                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17030                                        |Context.BIND_IMPORTANT)) != 0) {
17031                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17032                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17033                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17034                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17035                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17036                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17037                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17038                                    adj = clientAdj;
17039                                } else {
17040                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17041                                        adj = ProcessList.VISIBLE_APP_ADJ;
17042                                    }
17043                                }
17044                                if (!client.cached) {
17045                                    app.cached = false;
17046                                }
17047                                adjType = "service";
17048                            }
17049                        }
17050                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17051                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17052                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17053                            }
17054                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17055                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17056                                    // Special handling of clients who are in the top state.
17057                                    // We *may* want to consider this process to be in the
17058                                    // top state as well, but only if there is not another
17059                                    // reason for it to be running.  Being on the top is a
17060                                    // special state, meaning you are specifically running
17061                                    // for the current top app.  If the process is already
17062                                    // running in the background for some other reason, it
17063                                    // is more important to continue considering it to be
17064                                    // in the background state.
17065                                    mayBeTop = true;
17066                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17067                                } else {
17068                                    // Special handling for above-top states (persistent
17069                                    // processes).  These should not bring the current process
17070                                    // into the top state, since they are not on top.  Instead
17071                                    // give them the best state after that.
17072                                    clientProcState =
17073                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17074                                }
17075                            }
17076                        } else {
17077                            if (clientProcState <
17078                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17079                                clientProcState =
17080                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17081                            }
17082                        }
17083                        if (procState > clientProcState) {
17084                            procState = clientProcState;
17085                        }
17086                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17087                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17088                            app.pendingUiClean = true;
17089                        }
17090                        if (adjType != null) {
17091                            app.adjType = adjType;
17092                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17093                                    .REASON_SERVICE_IN_USE;
17094                            app.adjSource = cr.binding.client;
17095                            app.adjSourceProcState = clientProcState;
17096                            app.adjTarget = s.name;
17097                        }
17098                    }
17099                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17100                        app.treatLikeActivity = true;
17101                    }
17102                    final ActivityRecord a = cr.activity;
17103                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17104                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17105                                (a.visible || a.state == ActivityState.RESUMED
17106                                 || a.state == ActivityState.PAUSING)) {
17107                            adj = ProcessList.FOREGROUND_APP_ADJ;
17108                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17109                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17110                            }
17111                            app.cached = false;
17112                            app.adjType = "service";
17113                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17114                                    .REASON_SERVICE_IN_USE;
17115                            app.adjSource = a;
17116                            app.adjSourceProcState = procState;
17117                            app.adjTarget = s.name;
17118                        }
17119                    }
17120                }
17121            }
17122        }
17123
17124        for (int provi = app.pubProviders.size()-1;
17125                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17126                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17127                        || procState > ActivityManager.PROCESS_STATE_TOP);
17128                provi--) {
17129            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17130            for (int i = cpr.connections.size()-1;
17131                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17132                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17133                            || procState > ActivityManager.PROCESS_STATE_TOP);
17134                    i--) {
17135                ContentProviderConnection conn = cpr.connections.get(i);
17136                ProcessRecord client = conn.client;
17137                if (client == app) {
17138                    // Being our own client is not interesting.
17139                    continue;
17140                }
17141                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17142                int clientProcState = client.curProcState;
17143                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17144                    // If the other app is cached for any reason, for purposes here
17145                    // we are going to consider it empty.
17146                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17147                }
17148                if (adj > clientAdj) {
17149                    if (app.hasShownUi && app != mHomeProcess
17150                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17151                        app.adjType = "cch-ui-provider";
17152                    } else {
17153                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17154                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17155                        app.adjType = "provider";
17156                    }
17157                    app.cached &= client.cached;
17158                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17159                            .REASON_PROVIDER_IN_USE;
17160                    app.adjSource = client;
17161                    app.adjSourceProcState = clientProcState;
17162                    app.adjTarget = cpr.name;
17163                }
17164                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17165                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17166                        // Special handling of clients who are in the top state.
17167                        // We *may* want to consider this process to be in the
17168                        // top state as well, but only if there is not another
17169                        // reason for it to be running.  Being on the top is a
17170                        // special state, meaning you are specifically running
17171                        // for the current top app.  If the process is already
17172                        // running in the background for some other reason, it
17173                        // is more important to continue considering it to be
17174                        // in the background state.
17175                        mayBeTop = true;
17176                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17177                    } else {
17178                        // Special handling for above-top states (persistent
17179                        // processes).  These should not bring the current process
17180                        // into the top state, since they are not on top.  Instead
17181                        // give them the best state after that.
17182                        clientProcState =
17183                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17184                    }
17185                }
17186                if (procState > clientProcState) {
17187                    procState = clientProcState;
17188                }
17189                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17190                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17191                }
17192            }
17193            // If the provider has external (non-framework) process
17194            // dependencies, ensure that its adjustment is at least
17195            // FOREGROUND_APP_ADJ.
17196            if (cpr.hasExternalProcessHandles()) {
17197                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17198                    adj = ProcessList.FOREGROUND_APP_ADJ;
17199                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17200                    app.cached = false;
17201                    app.adjType = "provider";
17202                    app.adjTarget = cpr.name;
17203                }
17204                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17205                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17206                }
17207            }
17208        }
17209
17210        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17211            // A client of one of our services or providers is in the top state.  We
17212            // *may* want to be in the top state, but not if we are already running in
17213            // the background for some other reason.  For the decision here, we are going
17214            // to pick out a few specific states that we want to remain in when a client
17215            // is top (states that tend to be longer-term) and otherwise allow it to go
17216            // to the top state.
17217            switch (procState) {
17218                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17219                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17220                case ActivityManager.PROCESS_STATE_SERVICE:
17221                    // These all are longer-term states, so pull them up to the top
17222                    // of the background states, but not all the way to the top state.
17223                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17224                    break;
17225                default:
17226                    // Otherwise, top is a better choice, so take it.
17227                    procState = ActivityManager.PROCESS_STATE_TOP;
17228                    break;
17229            }
17230        }
17231
17232        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17233            if (app.hasClientActivities) {
17234                // This is a cached process, but with client activities.  Mark it so.
17235                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17236                app.adjType = "cch-client-act";
17237            } else if (app.treatLikeActivity) {
17238                // This is a cached process, but somebody wants us to treat it like it has
17239                // an activity, okay!
17240                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17241                app.adjType = "cch-as-act";
17242            }
17243        }
17244
17245        if (adj == ProcessList.SERVICE_ADJ) {
17246            if (doingAll) {
17247                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17248                mNewNumServiceProcs++;
17249                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17250                if (!app.serviceb) {
17251                    // This service isn't far enough down on the LRU list to
17252                    // normally be a B service, but if we are low on RAM and it
17253                    // is large we want to force it down since we would prefer to
17254                    // keep launcher over it.
17255                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17256                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17257                        app.serviceHighRam = true;
17258                        app.serviceb = true;
17259                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17260                    } else {
17261                        mNewNumAServiceProcs++;
17262                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17263                    }
17264                } else {
17265                    app.serviceHighRam = false;
17266                }
17267            }
17268            if (app.serviceb) {
17269                adj = ProcessList.SERVICE_B_ADJ;
17270            }
17271        }
17272
17273        app.curRawAdj = adj;
17274
17275        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17276        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17277        if (adj > app.maxAdj) {
17278            adj = app.maxAdj;
17279            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17280                schedGroup = Process.THREAD_GROUP_DEFAULT;
17281            }
17282        }
17283
17284        // Do final modification to adj.  Everything we do between here and applying
17285        // the final setAdj must be done in this function, because we will also use
17286        // it when computing the final cached adj later.  Note that we don't need to
17287        // worry about this for max adj above, since max adj will always be used to
17288        // keep it out of the cached vaues.
17289        app.curAdj = app.modifyRawOomAdj(adj);
17290        app.curSchedGroup = schedGroup;
17291        app.curProcState = procState;
17292        app.foregroundActivities = foregroundActivities;
17293
17294        return app.curRawAdj;
17295    }
17296
17297    /**
17298     * Schedule PSS collection of a process.
17299     */
17300    void requestPssLocked(ProcessRecord proc, int procState) {
17301        if (mPendingPssProcesses.contains(proc)) {
17302            return;
17303        }
17304        if (mPendingPssProcesses.size() == 0) {
17305            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17306        }
17307        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17308        proc.pssProcState = procState;
17309        mPendingPssProcesses.add(proc);
17310    }
17311
17312    /**
17313     * Schedule PSS collection of all processes.
17314     */
17315    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17316        if (!always) {
17317            if (now < (mLastFullPssTime +
17318                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17319                return;
17320            }
17321        }
17322        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17323        mLastFullPssTime = now;
17324        mFullPssPending = true;
17325        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17326        mPendingPssProcesses.clear();
17327        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17328            ProcessRecord app = mLruProcesses.get(i);
17329            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17330                app.pssProcState = app.setProcState;
17331                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17332                        isSleeping(), now);
17333                mPendingPssProcesses.add(app);
17334            }
17335        }
17336        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17337    }
17338
17339    /**
17340     * Ask a given process to GC right now.
17341     */
17342    final void performAppGcLocked(ProcessRecord app) {
17343        try {
17344            app.lastRequestedGc = SystemClock.uptimeMillis();
17345            if (app.thread != null) {
17346                if (app.reportLowMemory) {
17347                    app.reportLowMemory = false;
17348                    app.thread.scheduleLowMemory();
17349                } else {
17350                    app.thread.processInBackground();
17351                }
17352            }
17353        } catch (Exception e) {
17354            // whatever.
17355        }
17356    }
17357
17358    /**
17359     * Returns true if things are idle enough to perform GCs.
17360     */
17361    private final boolean canGcNowLocked() {
17362        boolean processingBroadcasts = false;
17363        for (BroadcastQueue q : mBroadcastQueues) {
17364            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17365                processingBroadcasts = true;
17366            }
17367        }
17368        return !processingBroadcasts
17369                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17370    }
17371
17372    /**
17373     * Perform GCs on all processes that are waiting for it, but only
17374     * if things are idle.
17375     */
17376    final void performAppGcsLocked() {
17377        final int N = mProcessesToGc.size();
17378        if (N <= 0) {
17379            return;
17380        }
17381        if (canGcNowLocked()) {
17382            while (mProcessesToGc.size() > 0) {
17383                ProcessRecord proc = mProcessesToGc.remove(0);
17384                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17385                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17386                            <= SystemClock.uptimeMillis()) {
17387                        // To avoid spamming the system, we will GC processes one
17388                        // at a time, waiting a few seconds between each.
17389                        performAppGcLocked(proc);
17390                        scheduleAppGcsLocked();
17391                        return;
17392                    } else {
17393                        // It hasn't been long enough since we last GCed this
17394                        // process...  put it in the list to wait for its time.
17395                        addProcessToGcListLocked(proc);
17396                        break;
17397                    }
17398                }
17399            }
17400
17401            scheduleAppGcsLocked();
17402        }
17403    }
17404
17405    /**
17406     * If all looks good, perform GCs on all processes waiting for them.
17407     */
17408    final void performAppGcsIfAppropriateLocked() {
17409        if (canGcNowLocked()) {
17410            performAppGcsLocked();
17411            return;
17412        }
17413        // Still not idle, wait some more.
17414        scheduleAppGcsLocked();
17415    }
17416
17417    /**
17418     * Schedule the execution of all pending app GCs.
17419     */
17420    final void scheduleAppGcsLocked() {
17421        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17422
17423        if (mProcessesToGc.size() > 0) {
17424            // Schedule a GC for the time to the next process.
17425            ProcessRecord proc = mProcessesToGc.get(0);
17426            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17427
17428            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17429            long now = SystemClock.uptimeMillis();
17430            if (when < (now+GC_TIMEOUT)) {
17431                when = now + GC_TIMEOUT;
17432            }
17433            mHandler.sendMessageAtTime(msg, when);
17434        }
17435    }
17436
17437    /**
17438     * Add a process to the array of processes waiting to be GCed.  Keeps the
17439     * list in sorted order by the last GC time.  The process can't already be
17440     * on the list.
17441     */
17442    final void addProcessToGcListLocked(ProcessRecord proc) {
17443        boolean added = false;
17444        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17445            if (mProcessesToGc.get(i).lastRequestedGc <
17446                    proc.lastRequestedGc) {
17447                added = true;
17448                mProcessesToGc.add(i+1, proc);
17449                break;
17450            }
17451        }
17452        if (!added) {
17453            mProcessesToGc.add(0, proc);
17454        }
17455    }
17456
17457    /**
17458     * Set up to ask a process to GC itself.  This will either do it
17459     * immediately, or put it on the list of processes to gc the next
17460     * time things are idle.
17461     */
17462    final void scheduleAppGcLocked(ProcessRecord app) {
17463        long now = SystemClock.uptimeMillis();
17464        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17465            return;
17466        }
17467        if (!mProcessesToGc.contains(app)) {
17468            addProcessToGcListLocked(app);
17469            scheduleAppGcsLocked();
17470        }
17471    }
17472
17473    final void checkExcessivePowerUsageLocked(boolean doKills) {
17474        updateCpuStatsNow();
17475
17476        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17477        boolean doWakeKills = doKills;
17478        boolean doCpuKills = doKills;
17479        if (mLastPowerCheckRealtime == 0) {
17480            doWakeKills = false;
17481        }
17482        if (mLastPowerCheckUptime == 0) {
17483            doCpuKills = false;
17484        }
17485        if (stats.isScreenOn()) {
17486            doWakeKills = false;
17487        }
17488        final long curRealtime = SystemClock.elapsedRealtime();
17489        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17490        final long curUptime = SystemClock.uptimeMillis();
17491        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17492        mLastPowerCheckRealtime = curRealtime;
17493        mLastPowerCheckUptime = curUptime;
17494        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17495            doWakeKills = false;
17496        }
17497        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17498            doCpuKills = false;
17499        }
17500        int i = mLruProcesses.size();
17501        while (i > 0) {
17502            i--;
17503            ProcessRecord app = mLruProcesses.get(i);
17504            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17505                long wtime;
17506                synchronized (stats) {
17507                    wtime = stats.getProcessWakeTime(app.info.uid,
17508                            app.pid, curRealtime);
17509                }
17510                long wtimeUsed = wtime - app.lastWakeTime;
17511                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17512                if (DEBUG_POWER) {
17513                    StringBuilder sb = new StringBuilder(128);
17514                    sb.append("Wake for ");
17515                    app.toShortString(sb);
17516                    sb.append(": over ");
17517                    TimeUtils.formatDuration(realtimeSince, sb);
17518                    sb.append(" used ");
17519                    TimeUtils.formatDuration(wtimeUsed, sb);
17520                    sb.append(" (");
17521                    sb.append((wtimeUsed*100)/realtimeSince);
17522                    sb.append("%)");
17523                    Slog.i(TAG, sb.toString());
17524                    sb.setLength(0);
17525                    sb.append("CPU for ");
17526                    app.toShortString(sb);
17527                    sb.append(": over ");
17528                    TimeUtils.formatDuration(uptimeSince, sb);
17529                    sb.append(" used ");
17530                    TimeUtils.formatDuration(cputimeUsed, sb);
17531                    sb.append(" (");
17532                    sb.append((cputimeUsed*100)/uptimeSince);
17533                    sb.append("%)");
17534                    Slog.i(TAG, sb.toString());
17535                }
17536                // If a process has held a wake lock for more
17537                // than 50% of the time during this period,
17538                // that sounds bad.  Kill!
17539                if (doWakeKills && realtimeSince > 0
17540                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17541                    synchronized (stats) {
17542                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17543                                realtimeSince, wtimeUsed);
17544                    }
17545                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17546                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17547                } else if (doCpuKills && uptimeSince > 0
17548                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17549                    synchronized (stats) {
17550                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17551                                uptimeSince, cputimeUsed);
17552                    }
17553                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17554                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17555                } else {
17556                    app.lastWakeTime = wtime;
17557                    app.lastCpuTime = app.curCpuTime;
17558                }
17559            }
17560        }
17561    }
17562
17563    private final boolean applyOomAdjLocked(ProcessRecord app,
17564            ProcessRecord TOP_APP, boolean doingAll, long now) {
17565        boolean success = true;
17566
17567        if (app.curRawAdj != app.setRawAdj) {
17568            app.setRawAdj = app.curRawAdj;
17569        }
17570
17571        int changes = 0;
17572
17573        if (app.curAdj != app.setAdj) {
17574            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17575            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17576                TAG, "Set " + app.pid + " " + app.processName +
17577                " adj " + app.curAdj + ": " + app.adjType);
17578            app.setAdj = app.curAdj;
17579        }
17580
17581        if (app.setSchedGroup != app.curSchedGroup) {
17582            app.setSchedGroup = app.curSchedGroup;
17583            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17584                    "Setting process group of " + app.processName
17585                    + " to " + app.curSchedGroup);
17586            if (app.waitingToKill != null &&
17587                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17588                app.kill(app.waitingToKill, true);
17589                success = false;
17590            } else {
17591                if (true) {
17592                    long oldId = Binder.clearCallingIdentity();
17593                    try {
17594                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17595                    } catch (Exception e) {
17596                        Slog.w(TAG, "Failed setting process group of " + app.pid
17597                                + " to " + app.curSchedGroup);
17598                        e.printStackTrace();
17599                    } finally {
17600                        Binder.restoreCallingIdentity(oldId);
17601                    }
17602                } else {
17603                    if (app.thread != null) {
17604                        try {
17605                            app.thread.setSchedulingGroup(app.curSchedGroup);
17606                        } catch (RemoteException e) {
17607                        }
17608                    }
17609                }
17610                Process.setSwappiness(app.pid,
17611                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17612            }
17613        }
17614        if (app.repForegroundActivities != app.foregroundActivities) {
17615            app.repForegroundActivities = app.foregroundActivities;
17616            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17617        }
17618        if (app.repProcState != app.curProcState) {
17619            app.repProcState = app.curProcState;
17620            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17621            if (app.thread != null) {
17622                try {
17623                    if (false) {
17624                        //RuntimeException h = new RuntimeException("here");
17625                        Slog.i(TAG, "Sending new process state " + app.repProcState
17626                                + " to " + app /*, h*/);
17627                    }
17628                    app.thread.setProcessState(app.repProcState);
17629                } catch (RemoteException e) {
17630                }
17631            }
17632        }
17633        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17634                app.setProcState)) {
17635            app.lastStateTime = now;
17636            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17637                    isSleeping(), now);
17638            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17639                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17640                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17641                    + (app.nextPssTime-now) + ": " + app);
17642        } else {
17643            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17644                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17645                requestPssLocked(app, app.setProcState);
17646                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17647                        isSleeping(), now);
17648            } else if (false && DEBUG_PSS) {
17649                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17650            }
17651        }
17652        if (app.setProcState != app.curProcState) {
17653            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17654                    "Proc state change of " + app.processName
17655                    + " to " + app.curProcState);
17656            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17657            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17658            if (setImportant && !curImportant) {
17659                // This app is no longer something we consider important enough to allow to
17660                // use arbitrary amounts of battery power.  Note
17661                // its current wake lock time to later know to kill it if
17662                // it is not behaving well.
17663                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17664                synchronized (stats) {
17665                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17666                            app.pid, SystemClock.elapsedRealtime());
17667                }
17668                app.lastCpuTime = app.curCpuTime;
17669
17670            }
17671            app.setProcState = app.curProcState;
17672            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17673                app.notCachedSinceIdle = false;
17674            }
17675            if (!doingAll) {
17676                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17677            } else {
17678                app.procStateChanged = true;
17679            }
17680        }
17681
17682        if (changes != 0) {
17683            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17684            int i = mPendingProcessChanges.size()-1;
17685            ProcessChangeItem item = null;
17686            while (i >= 0) {
17687                item = mPendingProcessChanges.get(i);
17688                if (item.pid == app.pid) {
17689                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17690                    break;
17691                }
17692                i--;
17693            }
17694            if (i < 0) {
17695                // No existing item in pending changes; need a new one.
17696                final int NA = mAvailProcessChanges.size();
17697                if (NA > 0) {
17698                    item = mAvailProcessChanges.remove(NA-1);
17699                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17700                } else {
17701                    item = new ProcessChangeItem();
17702                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17703                }
17704                item.changes = 0;
17705                item.pid = app.pid;
17706                item.uid = app.info.uid;
17707                if (mPendingProcessChanges.size() == 0) {
17708                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17709                            "*** Enqueueing dispatch processes changed!");
17710                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17711                }
17712                mPendingProcessChanges.add(item);
17713            }
17714            item.changes |= changes;
17715            item.processState = app.repProcState;
17716            item.foregroundActivities = app.repForegroundActivities;
17717            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17718                    + Integer.toHexString(System.identityHashCode(item))
17719                    + " " + app.toShortString() + ": changes=" + item.changes
17720                    + " procState=" + item.processState
17721                    + " foreground=" + item.foregroundActivities
17722                    + " type=" + app.adjType + " source=" + app.adjSource
17723                    + " target=" + app.adjTarget);
17724        }
17725
17726        return success;
17727    }
17728
17729    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17730        if (proc.thread != null) {
17731            if (proc.baseProcessTracker != null) {
17732                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17733            }
17734            if (proc.repProcState >= 0) {
17735                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17736                        proc.repProcState);
17737            }
17738        }
17739    }
17740
17741    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17742            ProcessRecord TOP_APP, boolean doingAll, long now) {
17743        if (app.thread == null) {
17744            return false;
17745        }
17746
17747        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17748
17749        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17750    }
17751
17752    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17753            boolean oomAdj) {
17754        if (isForeground != proc.foregroundServices) {
17755            proc.foregroundServices = isForeground;
17756            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17757                    proc.info.uid);
17758            if (isForeground) {
17759                if (curProcs == null) {
17760                    curProcs = new ArrayList<ProcessRecord>();
17761                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17762                }
17763                if (!curProcs.contains(proc)) {
17764                    curProcs.add(proc);
17765                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17766                            proc.info.packageName, proc.info.uid);
17767                }
17768            } else {
17769                if (curProcs != null) {
17770                    if (curProcs.remove(proc)) {
17771                        mBatteryStatsService.noteEvent(
17772                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17773                                proc.info.packageName, proc.info.uid);
17774                        if (curProcs.size() <= 0) {
17775                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17776                        }
17777                    }
17778                }
17779            }
17780            if (oomAdj) {
17781                updateOomAdjLocked();
17782            }
17783        }
17784    }
17785
17786    private final ActivityRecord resumedAppLocked() {
17787        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17788        String pkg;
17789        int uid;
17790        if (act != null) {
17791            pkg = act.packageName;
17792            uid = act.info.applicationInfo.uid;
17793        } else {
17794            pkg = null;
17795            uid = -1;
17796        }
17797        // Has the UID or resumed package name changed?
17798        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17799                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17800            if (mCurResumedPackage != null) {
17801                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17802                        mCurResumedPackage, mCurResumedUid);
17803            }
17804            mCurResumedPackage = pkg;
17805            mCurResumedUid = uid;
17806            if (mCurResumedPackage != null) {
17807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17808                        mCurResumedPackage, mCurResumedUid);
17809            }
17810        }
17811        return act;
17812    }
17813
17814    final boolean updateOomAdjLocked(ProcessRecord app) {
17815        final ActivityRecord TOP_ACT = resumedAppLocked();
17816        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17817        final boolean wasCached = app.cached;
17818
17819        mAdjSeq++;
17820
17821        // This is the desired cached adjusment we want to tell it to use.
17822        // If our app is currently cached, we know it, and that is it.  Otherwise,
17823        // we don't know it yet, and it needs to now be cached we will then
17824        // need to do a complete oom adj.
17825        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17826                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17827        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17828                SystemClock.uptimeMillis());
17829        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17830            // Changed to/from cached state, so apps after it in the LRU
17831            // list may also be changed.
17832            updateOomAdjLocked();
17833        }
17834        return success;
17835    }
17836
17837    final void updateOomAdjLocked() {
17838        final ActivityRecord TOP_ACT = resumedAppLocked();
17839        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17840        final long now = SystemClock.uptimeMillis();
17841        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17842        final int N = mLruProcesses.size();
17843
17844        if (false) {
17845            RuntimeException e = new RuntimeException();
17846            e.fillInStackTrace();
17847            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17848        }
17849
17850        mAdjSeq++;
17851        mNewNumServiceProcs = 0;
17852        mNewNumAServiceProcs = 0;
17853
17854        final int emptyProcessLimit;
17855        final int cachedProcessLimit;
17856        if (mProcessLimit <= 0) {
17857            emptyProcessLimit = cachedProcessLimit = 0;
17858        } else if (mProcessLimit == 1) {
17859            emptyProcessLimit = 1;
17860            cachedProcessLimit = 0;
17861        } else {
17862            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17863            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17864        }
17865
17866        // Let's determine how many processes we have running vs.
17867        // how many slots we have for background processes; we may want
17868        // to put multiple processes in a slot of there are enough of
17869        // them.
17870        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17871                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17872        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17873        if (numEmptyProcs > cachedProcessLimit) {
17874            // If there are more empty processes than our limit on cached
17875            // processes, then use the cached process limit for the factor.
17876            // This ensures that the really old empty processes get pushed
17877            // down to the bottom, so if we are running low on memory we will
17878            // have a better chance at keeping around more cached processes
17879            // instead of a gazillion empty processes.
17880            numEmptyProcs = cachedProcessLimit;
17881        }
17882        int emptyFactor = numEmptyProcs/numSlots;
17883        if (emptyFactor < 1) emptyFactor = 1;
17884        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17885        if (cachedFactor < 1) cachedFactor = 1;
17886        int stepCached = 0;
17887        int stepEmpty = 0;
17888        int numCached = 0;
17889        int numEmpty = 0;
17890        int numTrimming = 0;
17891
17892        mNumNonCachedProcs = 0;
17893        mNumCachedHiddenProcs = 0;
17894
17895        // First update the OOM adjustment for each of the
17896        // application processes based on their current state.
17897        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17898        int nextCachedAdj = curCachedAdj+1;
17899        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17900        int nextEmptyAdj = curEmptyAdj+2;
17901        for (int i=N-1; i>=0; i--) {
17902            ProcessRecord app = mLruProcesses.get(i);
17903            if (!app.killedByAm && app.thread != null) {
17904                app.procStateChanged = false;
17905                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17906
17907                // If we haven't yet assigned the final cached adj
17908                // to the process, do that now.
17909                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17910                    switch (app.curProcState) {
17911                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17912                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17913                            // This process is a cached process holding activities...
17914                            // assign it the next cached value for that type, and then
17915                            // step that cached level.
17916                            app.curRawAdj = curCachedAdj;
17917                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17918                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17919                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17920                                    + ")");
17921                            if (curCachedAdj != nextCachedAdj) {
17922                                stepCached++;
17923                                if (stepCached >= cachedFactor) {
17924                                    stepCached = 0;
17925                                    curCachedAdj = nextCachedAdj;
17926                                    nextCachedAdj += 2;
17927                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17928                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17929                                    }
17930                                }
17931                            }
17932                            break;
17933                        default:
17934                            // For everything else, assign next empty cached process
17935                            // level and bump that up.  Note that this means that
17936                            // long-running services that have dropped down to the
17937                            // cached level will be treated as empty (since their process
17938                            // state is still as a service), which is what we want.
17939                            app.curRawAdj = curEmptyAdj;
17940                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17941                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17942                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17943                                    + ")");
17944                            if (curEmptyAdj != nextEmptyAdj) {
17945                                stepEmpty++;
17946                                if (stepEmpty >= emptyFactor) {
17947                                    stepEmpty = 0;
17948                                    curEmptyAdj = nextEmptyAdj;
17949                                    nextEmptyAdj += 2;
17950                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17951                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17952                                    }
17953                                }
17954                            }
17955                            break;
17956                    }
17957                }
17958
17959                applyOomAdjLocked(app, TOP_APP, true, now);
17960
17961                // Count the number of process types.
17962                switch (app.curProcState) {
17963                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17964                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17965                        mNumCachedHiddenProcs++;
17966                        numCached++;
17967                        if (numCached > cachedProcessLimit) {
17968                            app.kill("cached #" + numCached, true);
17969                        }
17970                        break;
17971                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17972                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17973                                && app.lastActivityTime < oldTime) {
17974                            app.kill("empty for "
17975                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17976                                    / 1000) + "s", true);
17977                        } else {
17978                            numEmpty++;
17979                            if (numEmpty > emptyProcessLimit) {
17980                                app.kill("empty #" + numEmpty, true);
17981                            }
17982                        }
17983                        break;
17984                    default:
17985                        mNumNonCachedProcs++;
17986                        break;
17987                }
17988
17989                if (app.isolated && app.services.size() <= 0) {
17990                    // If this is an isolated process, and there are no
17991                    // services running in it, then the process is no longer
17992                    // needed.  We agressively kill these because we can by
17993                    // definition not re-use the same process again, and it is
17994                    // good to avoid having whatever code was running in them
17995                    // left sitting around after no longer needed.
17996                    app.kill("isolated not needed", true);
17997                }
17998
17999                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18000                        && !app.killedByAm) {
18001                    numTrimming++;
18002                }
18003            }
18004        }
18005
18006        mNumServiceProcs = mNewNumServiceProcs;
18007
18008        // Now determine the memory trimming level of background processes.
18009        // Unfortunately we need to start at the back of the list to do this
18010        // properly.  We only do this if the number of background apps we
18011        // are managing to keep around is less than half the maximum we desire;
18012        // if we are keeping a good number around, we'll let them use whatever
18013        // memory they want.
18014        final int numCachedAndEmpty = numCached + numEmpty;
18015        int memFactor;
18016        if (numCached <= ProcessList.TRIM_CACHED_APPS
18017                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18018            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18019                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18020            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18021                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18022            } else {
18023                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18024            }
18025        } else {
18026            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18027        }
18028        // We always allow the memory level to go up (better).  We only allow it to go
18029        // down if we are in a state where that is allowed, *and* the total number of processes
18030        // has gone down since last time.
18031        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18032                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18033                + " last=" + mLastNumProcesses);
18034        if (memFactor > mLastMemoryLevel) {
18035            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18036                memFactor = mLastMemoryLevel;
18037                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18038            }
18039        }
18040        mLastMemoryLevel = memFactor;
18041        mLastNumProcesses = mLruProcesses.size();
18042        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18043        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18044        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18045            if (mLowRamStartTime == 0) {
18046                mLowRamStartTime = now;
18047            }
18048            int step = 0;
18049            int fgTrimLevel;
18050            switch (memFactor) {
18051                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18052                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18053                    break;
18054                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18055                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18056                    break;
18057                default:
18058                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18059                    break;
18060            }
18061            int factor = numTrimming/3;
18062            int minFactor = 2;
18063            if (mHomeProcess != null) minFactor++;
18064            if (mPreviousProcess != null) minFactor++;
18065            if (factor < minFactor) factor = minFactor;
18066            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18067            for (int i=N-1; i>=0; i--) {
18068                ProcessRecord app = mLruProcesses.get(i);
18069                if (allChanged || app.procStateChanged) {
18070                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18071                    app.procStateChanged = false;
18072                }
18073                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18074                        && !app.killedByAm) {
18075                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18076                        try {
18077                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18078                                    "Trimming memory of " + app.processName
18079                                    + " to " + curLevel);
18080                            app.thread.scheduleTrimMemory(curLevel);
18081                        } catch (RemoteException e) {
18082                        }
18083                        if (false) {
18084                            // For now we won't do this; our memory trimming seems
18085                            // to be good enough at this point that destroying
18086                            // activities causes more harm than good.
18087                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18088                                    && app != mHomeProcess && app != mPreviousProcess) {
18089                                // Need to do this on its own message because the stack may not
18090                                // be in a consistent state at this point.
18091                                // For these apps we will also finish their activities
18092                                // to help them free memory.
18093                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18094                            }
18095                        }
18096                    }
18097                    app.trimMemoryLevel = curLevel;
18098                    step++;
18099                    if (step >= factor) {
18100                        step = 0;
18101                        switch (curLevel) {
18102                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18103                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18104                                break;
18105                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18106                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18107                                break;
18108                        }
18109                    }
18110                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18111                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18112                            && app.thread != null) {
18113                        try {
18114                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18115                                    "Trimming memory of heavy-weight " + app.processName
18116                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18117                            app.thread.scheduleTrimMemory(
18118                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18119                        } catch (RemoteException e) {
18120                        }
18121                    }
18122                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18123                } else {
18124                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18125                            || app.systemNoUi) && app.pendingUiClean) {
18126                        // If this application is now in the background and it
18127                        // had done UI, then give it the special trim level to
18128                        // have it free UI resources.
18129                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18130                        if (app.trimMemoryLevel < level && app.thread != null) {
18131                            try {
18132                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18133                                        "Trimming memory of bg-ui " + app.processName
18134                                        + " to " + level);
18135                                app.thread.scheduleTrimMemory(level);
18136                            } catch (RemoteException e) {
18137                            }
18138                        }
18139                        app.pendingUiClean = false;
18140                    }
18141                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18142                        try {
18143                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18144                                    "Trimming memory of fg " + app.processName
18145                                    + " to " + fgTrimLevel);
18146                            app.thread.scheduleTrimMemory(fgTrimLevel);
18147                        } catch (RemoteException e) {
18148                        }
18149                    }
18150                    app.trimMemoryLevel = fgTrimLevel;
18151                }
18152            }
18153        } else {
18154            if (mLowRamStartTime != 0) {
18155                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18156                mLowRamStartTime = 0;
18157            }
18158            for (int i=N-1; i>=0; i--) {
18159                ProcessRecord app = mLruProcesses.get(i);
18160                if (allChanged || app.procStateChanged) {
18161                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18162                    app.procStateChanged = false;
18163                }
18164                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18165                        || app.systemNoUi) && app.pendingUiClean) {
18166                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18167                            && app.thread != null) {
18168                        try {
18169                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18170                                    "Trimming memory of ui hidden " + app.processName
18171                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18172                            app.thread.scheduleTrimMemory(
18173                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18174                        } catch (RemoteException e) {
18175                        }
18176                    }
18177                    app.pendingUiClean = false;
18178                }
18179                app.trimMemoryLevel = 0;
18180            }
18181        }
18182
18183        if (mAlwaysFinishActivities) {
18184            // Need to do this on its own message because the stack may not
18185            // be in a consistent state at this point.
18186            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18187        }
18188
18189        if (allChanged) {
18190            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18191        }
18192
18193        if (mProcessStats.shouldWriteNowLocked(now)) {
18194            mHandler.post(new Runnable() {
18195                @Override public void run() {
18196                    synchronized (ActivityManagerService.this) {
18197                        mProcessStats.writeStateAsyncLocked();
18198                    }
18199                }
18200            });
18201        }
18202
18203        if (DEBUG_OOM_ADJ) {
18204            if (false) {
18205                RuntimeException here = new RuntimeException("here");
18206                here.fillInStackTrace();
18207                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18208            } else {
18209                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18210            }
18211        }
18212    }
18213
18214    final void trimApplications() {
18215        synchronized (this) {
18216            int i;
18217
18218            // First remove any unused application processes whose package
18219            // has been removed.
18220            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18221                final ProcessRecord app = mRemovedProcesses.get(i);
18222                if (app.activities.size() == 0
18223                        && app.curReceiver == null && app.services.size() == 0) {
18224                    Slog.i(
18225                        TAG, "Exiting empty application process "
18226                        + app.processName + " ("
18227                        + (app.thread != null ? app.thread.asBinder() : null)
18228                        + ")\n");
18229                    if (app.pid > 0 && app.pid != MY_PID) {
18230                        app.kill("empty", false);
18231                    } else {
18232                        try {
18233                            app.thread.scheduleExit();
18234                        } catch (Exception e) {
18235                            // Ignore exceptions.
18236                        }
18237                    }
18238                    cleanUpApplicationRecordLocked(app, false, true, -1);
18239                    mRemovedProcesses.remove(i);
18240
18241                    if (app.persistent) {
18242                        addAppLocked(app.info, false, null /* ABI override */);
18243                    }
18244                }
18245            }
18246
18247            // Now update the oom adj for all processes.
18248            updateOomAdjLocked();
18249        }
18250    }
18251
18252    /** This method sends the specified signal to each of the persistent apps */
18253    public void signalPersistentProcesses(int sig) throws RemoteException {
18254        if (sig != Process.SIGNAL_USR1) {
18255            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18256        }
18257
18258        synchronized (this) {
18259            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18260                    != PackageManager.PERMISSION_GRANTED) {
18261                throw new SecurityException("Requires permission "
18262                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18263            }
18264
18265            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18266                ProcessRecord r = mLruProcesses.get(i);
18267                if (r.thread != null && r.persistent) {
18268                    Process.sendSignal(r.pid, sig);
18269                }
18270            }
18271        }
18272    }
18273
18274    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18275        if (proc == null || proc == mProfileProc) {
18276            proc = mProfileProc;
18277            profileType = mProfileType;
18278            clearProfilerLocked();
18279        }
18280        if (proc == null) {
18281            return;
18282        }
18283        try {
18284            proc.thread.profilerControl(false, null, profileType);
18285        } catch (RemoteException e) {
18286            throw new IllegalStateException("Process disappeared");
18287        }
18288    }
18289
18290    private void clearProfilerLocked() {
18291        if (mProfileFd != null) {
18292            try {
18293                mProfileFd.close();
18294            } catch (IOException e) {
18295            }
18296        }
18297        mProfileApp = null;
18298        mProfileProc = null;
18299        mProfileFile = null;
18300        mProfileType = 0;
18301        mAutoStopProfiler = false;
18302        mSamplingInterval = 0;
18303    }
18304
18305    public boolean profileControl(String process, int userId, boolean start,
18306            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18307
18308        try {
18309            synchronized (this) {
18310                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18311                // its own permission.
18312                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18313                        != PackageManager.PERMISSION_GRANTED) {
18314                    throw new SecurityException("Requires permission "
18315                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18316                }
18317
18318                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18319                    throw new IllegalArgumentException("null profile info or fd");
18320                }
18321
18322                ProcessRecord proc = null;
18323                if (process != null) {
18324                    proc = findProcessLocked(process, userId, "profileControl");
18325                }
18326
18327                if (start && (proc == null || proc.thread == null)) {
18328                    throw new IllegalArgumentException("Unknown process: " + process);
18329                }
18330
18331                if (start) {
18332                    stopProfilerLocked(null, 0);
18333                    setProfileApp(proc.info, proc.processName, profilerInfo);
18334                    mProfileProc = proc;
18335                    mProfileType = profileType;
18336                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18337                    try {
18338                        fd = fd.dup();
18339                    } catch (IOException e) {
18340                        fd = null;
18341                    }
18342                    profilerInfo.profileFd = fd;
18343                    proc.thread.profilerControl(start, profilerInfo, profileType);
18344                    fd = null;
18345                    mProfileFd = null;
18346                } else {
18347                    stopProfilerLocked(proc, profileType);
18348                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18349                        try {
18350                            profilerInfo.profileFd.close();
18351                        } catch (IOException e) {
18352                        }
18353                    }
18354                }
18355
18356                return true;
18357            }
18358        } catch (RemoteException e) {
18359            throw new IllegalStateException("Process disappeared");
18360        } finally {
18361            if (profilerInfo != null && profilerInfo.profileFd != null) {
18362                try {
18363                    profilerInfo.profileFd.close();
18364                } catch (IOException e) {
18365                }
18366            }
18367        }
18368    }
18369
18370    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18372                userId, true, ALLOW_FULL_ONLY, callName, null);
18373        ProcessRecord proc = null;
18374        try {
18375            int pid = Integer.parseInt(process);
18376            synchronized (mPidsSelfLocked) {
18377                proc = mPidsSelfLocked.get(pid);
18378            }
18379        } catch (NumberFormatException e) {
18380        }
18381
18382        if (proc == null) {
18383            ArrayMap<String, SparseArray<ProcessRecord>> all
18384                    = mProcessNames.getMap();
18385            SparseArray<ProcessRecord> procs = all.get(process);
18386            if (procs != null && procs.size() > 0) {
18387                proc = procs.valueAt(0);
18388                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18389                    for (int i=1; i<procs.size(); i++) {
18390                        ProcessRecord thisProc = procs.valueAt(i);
18391                        if (thisProc.userId == userId) {
18392                            proc = thisProc;
18393                            break;
18394                        }
18395                    }
18396                }
18397            }
18398        }
18399
18400        return proc;
18401    }
18402
18403    public boolean dumpHeap(String process, int userId, boolean managed,
18404            String path, ParcelFileDescriptor fd) throws RemoteException {
18405
18406        try {
18407            synchronized (this) {
18408                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18409                // its own permission (same as profileControl).
18410                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18411                        != PackageManager.PERMISSION_GRANTED) {
18412                    throw new SecurityException("Requires permission "
18413                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18414                }
18415
18416                if (fd == null) {
18417                    throw new IllegalArgumentException("null fd");
18418                }
18419
18420                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18421                if (proc == null || proc.thread == null) {
18422                    throw new IllegalArgumentException("Unknown process: " + process);
18423                }
18424
18425                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18426                if (!isDebuggable) {
18427                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18428                        throw new SecurityException("Process not debuggable: " + proc);
18429                    }
18430                }
18431
18432                proc.thread.dumpHeap(managed, path, fd);
18433                fd = null;
18434                return true;
18435            }
18436        } catch (RemoteException e) {
18437            throw new IllegalStateException("Process disappeared");
18438        } finally {
18439            if (fd != null) {
18440                try {
18441                    fd.close();
18442                } catch (IOException e) {
18443                }
18444            }
18445        }
18446    }
18447
18448    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18449    public void monitor() {
18450        synchronized (this) { }
18451    }
18452
18453    void onCoreSettingsChange(Bundle settings) {
18454        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18455            ProcessRecord processRecord = mLruProcesses.get(i);
18456            try {
18457                if (processRecord.thread != null) {
18458                    processRecord.thread.setCoreSettings(settings);
18459                }
18460            } catch (RemoteException re) {
18461                /* ignore */
18462            }
18463        }
18464    }
18465
18466    // Multi-user methods
18467
18468    /**
18469     * Start user, if its not already running, but don't bring it to foreground.
18470     */
18471    @Override
18472    public boolean startUserInBackground(final int userId) {
18473        return startUser(userId, /* foreground */ false);
18474    }
18475
18476    /**
18477     * Start user, if its not already running, and bring it to foreground.
18478     */
18479    boolean startUserInForeground(final int userId, Dialog dlg) {
18480        boolean result = startUser(userId, /* foreground */ true);
18481        dlg.dismiss();
18482        return result;
18483    }
18484
18485    /**
18486     * Refreshes the list of users related to the current user when either a
18487     * user switch happens or when a new related user is started in the
18488     * background.
18489     */
18490    private void updateCurrentProfileIdsLocked() {
18491        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18492                mCurrentUserId, false /* enabledOnly */);
18493        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18494        for (int i = 0; i < currentProfileIds.length; i++) {
18495            currentProfileIds[i] = profiles.get(i).id;
18496        }
18497        mCurrentProfileIds = currentProfileIds;
18498
18499        synchronized (mUserProfileGroupIdsSelfLocked) {
18500            mUserProfileGroupIdsSelfLocked.clear();
18501            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18502            for (int i = 0; i < users.size(); i++) {
18503                UserInfo user = users.get(i);
18504                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18505                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18506                }
18507            }
18508        }
18509    }
18510
18511    private Set getProfileIdsLocked(int userId) {
18512        Set userIds = new HashSet<Integer>();
18513        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18514                userId, false /* enabledOnly */);
18515        for (UserInfo user : profiles) {
18516            userIds.add(Integer.valueOf(user.id));
18517        }
18518        return userIds;
18519    }
18520
18521    @Override
18522    public boolean switchUser(final int userId) {
18523        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18524        String userName;
18525        synchronized (this) {
18526            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18527            if (userInfo == null) {
18528                Slog.w(TAG, "No user info for user #" + userId);
18529                return false;
18530            }
18531            if (userInfo.isManagedProfile()) {
18532                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18533                return false;
18534            }
18535            userName = userInfo.name;
18536            mTargetUserId = userId;
18537        }
18538        mHandler.removeMessages(START_USER_SWITCH_MSG);
18539        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18540        return true;
18541    }
18542
18543    private void showUserSwitchDialog(int userId, String userName) {
18544        // The dialog will show and then initiate the user switch by calling startUserInForeground
18545        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18546                true /* above system */);
18547        d.show();
18548    }
18549
18550    private boolean startUser(final int userId, final boolean foreground) {
18551        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18552                != PackageManager.PERMISSION_GRANTED) {
18553            String msg = "Permission Denial: switchUser() from pid="
18554                    + Binder.getCallingPid()
18555                    + ", uid=" + Binder.getCallingUid()
18556                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18557            Slog.w(TAG, msg);
18558            throw new SecurityException(msg);
18559        }
18560
18561        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18562
18563        final long ident = Binder.clearCallingIdentity();
18564        try {
18565            synchronized (this) {
18566                final int oldUserId = mCurrentUserId;
18567                if (oldUserId == userId) {
18568                    return true;
18569                }
18570
18571                mStackSupervisor.setLockTaskModeLocked(null, false);
18572
18573                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18574                if (userInfo == null) {
18575                    Slog.w(TAG, "No user info for user #" + userId);
18576                    return false;
18577                }
18578                if (foreground && userInfo.isManagedProfile()) {
18579                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18580                    return false;
18581                }
18582
18583                if (foreground) {
18584                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18585                            R.anim.screen_user_enter);
18586                }
18587
18588                boolean needStart = false;
18589
18590                // If the user we are switching to is not currently started, then
18591                // we need to start it now.
18592                if (mStartedUsers.get(userId) == null) {
18593                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18594                    updateStartedUserArrayLocked();
18595                    needStart = true;
18596                }
18597
18598                final Integer userIdInt = Integer.valueOf(userId);
18599                mUserLru.remove(userIdInt);
18600                mUserLru.add(userIdInt);
18601
18602                if (foreground) {
18603                    mCurrentUserId = userId;
18604                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18605                    updateCurrentProfileIdsLocked();
18606                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18607                    // Once the internal notion of the active user has switched, we lock the device
18608                    // with the option to show the user switcher on the keyguard.
18609                    mWindowManager.lockNow(null);
18610                } else {
18611                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18612                    updateCurrentProfileIdsLocked();
18613                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18614                    mUserLru.remove(currentUserIdInt);
18615                    mUserLru.add(currentUserIdInt);
18616                }
18617
18618                final UserStartedState uss = mStartedUsers.get(userId);
18619
18620                // Make sure user is in the started state.  If it is currently
18621                // stopping, we need to knock that off.
18622                if (uss.mState == UserStartedState.STATE_STOPPING) {
18623                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18624                    // so we can just fairly silently bring the user back from
18625                    // the almost-dead.
18626                    uss.mState = UserStartedState.STATE_RUNNING;
18627                    updateStartedUserArrayLocked();
18628                    needStart = true;
18629                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18630                    // This means ACTION_SHUTDOWN has been sent, so we will
18631                    // need to treat this as a new boot of the user.
18632                    uss.mState = UserStartedState.STATE_BOOTING;
18633                    updateStartedUserArrayLocked();
18634                    needStart = true;
18635                }
18636
18637                if (uss.mState == UserStartedState.STATE_BOOTING) {
18638                    // Booting up a new user, need to tell system services about it.
18639                    // Note that this is on the same handler as scheduling of broadcasts,
18640                    // which is important because it needs to go first.
18641                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18642                }
18643
18644                if (foreground) {
18645                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18646                            oldUserId));
18647                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18648                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18649                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18650                            oldUserId, userId, uss));
18651                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18652                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18653                }
18654
18655                if (needStart) {
18656                    // Send USER_STARTED broadcast
18657                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18658                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18659                            | Intent.FLAG_RECEIVER_FOREGROUND);
18660                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18661                    broadcastIntentLocked(null, null, intent,
18662                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18663                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18664                }
18665
18666                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18667                    if (userId != UserHandle.USER_OWNER) {
18668                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18669                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18670                        broadcastIntentLocked(null, null, intent, null,
18671                                new IIntentReceiver.Stub() {
18672                                    public void performReceive(Intent intent, int resultCode,
18673                                            String data, Bundle extras, boolean ordered,
18674                                            boolean sticky, int sendingUser) {
18675                                        onUserInitialized(uss, foreground, oldUserId, userId);
18676                                    }
18677                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18678                                true, false, MY_PID, Process.SYSTEM_UID,
18679                                userId);
18680                        uss.initializing = true;
18681                    } else {
18682                        getUserManagerLocked().makeInitialized(userInfo.id);
18683                    }
18684                }
18685
18686                if (foreground) {
18687                    if (!uss.initializing) {
18688                        moveUserToForeground(uss, oldUserId, userId);
18689                    }
18690                } else {
18691                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18692                }
18693
18694                if (needStart) {
18695                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18696                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18697                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18698                    broadcastIntentLocked(null, null, intent,
18699                            null, new IIntentReceiver.Stub() {
18700                                @Override
18701                                public void performReceive(Intent intent, int resultCode, String data,
18702                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18703                                        throws RemoteException {
18704                                }
18705                            }, 0, null, null,
18706                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18707                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18708                }
18709            }
18710        } finally {
18711            Binder.restoreCallingIdentity(ident);
18712        }
18713
18714        return true;
18715    }
18716
18717    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18718        long ident = Binder.clearCallingIdentity();
18719        try {
18720            Intent intent;
18721            if (oldUserId >= 0) {
18722                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18723                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18724                int count = profiles.size();
18725                for (int i = 0; i < count; i++) {
18726                    int profileUserId = profiles.get(i).id;
18727                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18728                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18729                            | Intent.FLAG_RECEIVER_FOREGROUND);
18730                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18731                    broadcastIntentLocked(null, null, intent,
18732                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18733                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18734                }
18735            }
18736            if (newUserId >= 0) {
18737                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18738                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18739                int count = profiles.size();
18740                for (int i = 0; i < count; i++) {
18741                    int profileUserId = profiles.get(i).id;
18742                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18743                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18744                            | Intent.FLAG_RECEIVER_FOREGROUND);
18745                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18746                    broadcastIntentLocked(null, null, intent,
18747                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18748                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18749                }
18750                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18751                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18752                        | Intent.FLAG_RECEIVER_FOREGROUND);
18753                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18754                broadcastIntentLocked(null, null, intent,
18755                        null, null, 0, null, null,
18756                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18757                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18758            }
18759        } finally {
18760            Binder.restoreCallingIdentity(ident);
18761        }
18762    }
18763
18764    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18765            final int newUserId) {
18766        final int N = mUserSwitchObservers.beginBroadcast();
18767        if (N > 0) {
18768            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18769                int mCount = 0;
18770                @Override
18771                public void sendResult(Bundle data) throws RemoteException {
18772                    synchronized (ActivityManagerService.this) {
18773                        if (mCurUserSwitchCallback == this) {
18774                            mCount++;
18775                            if (mCount == N) {
18776                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18777                            }
18778                        }
18779                    }
18780                }
18781            };
18782            synchronized (this) {
18783                uss.switching = true;
18784                mCurUserSwitchCallback = callback;
18785            }
18786            for (int i=0; i<N; i++) {
18787                try {
18788                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18789                            newUserId, callback);
18790                } catch (RemoteException e) {
18791                }
18792            }
18793        } else {
18794            synchronized (this) {
18795                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18796            }
18797        }
18798        mUserSwitchObservers.finishBroadcast();
18799    }
18800
18801    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18802        synchronized (this) {
18803            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18804            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18805        }
18806    }
18807
18808    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18809        mCurUserSwitchCallback = null;
18810        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18811        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18812                oldUserId, newUserId, uss));
18813    }
18814
18815    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18816        synchronized (this) {
18817            if (foreground) {
18818                moveUserToForeground(uss, oldUserId, newUserId);
18819            }
18820        }
18821
18822        completeSwitchAndInitalize(uss, newUserId, true, false);
18823    }
18824
18825    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18826        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18827        if (homeInFront) {
18828            startHomeActivityLocked(newUserId);
18829        } else {
18830            mStackSupervisor.resumeTopActivitiesLocked();
18831        }
18832        EventLogTags.writeAmSwitchUser(newUserId);
18833        getUserManagerLocked().userForeground(newUserId);
18834        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18835    }
18836
18837    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18838        completeSwitchAndInitalize(uss, newUserId, false, true);
18839    }
18840
18841    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18842            boolean clearInitializing, boolean clearSwitching) {
18843        boolean unfrozen = false;
18844        synchronized (this) {
18845            if (clearInitializing) {
18846                uss.initializing = false;
18847                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18848            }
18849            if (clearSwitching) {
18850                uss.switching = false;
18851            }
18852            if (!uss.switching && !uss.initializing) {
18853                mWindowManager.stopFreezingScreen();
18854                unfrozen = true;
18855            }
18856        }
18857        if (unfrozen) {
18858            final int N = mUserSwitchObservers.beginBroadcast();
18859            for (int i=0; i<N; i++) {
18860                try {
18861                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18862                } catch (RemoteException e) {
18863                }
18864            }
18865            mUserSwitchObservers.finishBroadcast();
18866        }
18867    }
18868
18869    void scheduleStartProfilesLocked() {
18870        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18871            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18872                    DateUtils.SECOND_IN_MILLIS);
18873        }
18874    }
18875
18876    void startProfilesLocked() {
18877        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18878        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18879                mCurrentUserId, false /* enabledOnly */);
18880        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18881        for (UserInfo user : profiles) {
18882            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18883                    && user.id != mCurrentUserId) {
18884                toStart.add(user);
18885            }
18886        }
18887        final int n = toStart.size();
18888        int i = 0;
18889        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18890            startUserInBackground(toStart.get(i).id);
18891        }
18892        if (i < n) {
18893            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18894        }
18895    }
18896
18897    void finishUserBoot(UserStartedState uss) {
18898        synchronized (this) {
18899            if (uss.mState == UserStartedState.STATE_BOOTING
18900                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18901                uss.mState = UserStartedState.STATE_RUNNING;
18902                final int userId = uss.mHandle.getIdentifier();
18903                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18904                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18905                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18906                broadcastIntentLocked(null, null, intent,
18907                        null, null, 0, null, null,
18908                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18909                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18910            }
18911        }
18912    }
18913
18914    void finishUserSwitch(UserStartedState uss) {
18915        synchronized (this) {
18916            finishUserBoot(uss);
18917
18918            startProfilesLocked();
18919
18920            int num = mUserLru.size();
18921            int i = 0;
18922            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18923                Integer oldUserId = mUserLru.get(i);
18924                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18925                if (oldUss == null) {
18926                    // Shouldn't happen, but be sane if it does.
18927                    mUserLru.remove(i);
18928                    num--;
18929                    continue;
18930                }
18931                if (oldUss.mState == UserStartedState.STATE_STOPPING
18932                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18933                    // This user is already stopping, doesn't count.
18934                    num--;
18935                    i++;
18936                    continue;
18937                }
18938                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18939                    // Owner and current can't be stopped, but count as running.
18940                    i++;
18941                    continue;
18942                }
18943                // This is a user to be stopped.
18944                stopUserLocked(oldUserId, null);
18945                num--;
18946                i++;
18947            }
18948        }
18949    }
18950
18951    @Override
18952    public int stopUser(final int userId, final IStopUserCallback callback) {
18953        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18954                != PackageManager.PERMISSION_GRANTED) {
18955            String msg = "Permission Denial: switchUser() from pid="
18956                    + Binder.getCallingPid()
18957                    + ", uid=" + Binder.getCallingUid()
18958                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18959            Slog.w(TAG, msg);
18960            throw new SecurityException(msg);
18961        }
18962        if (userId <= 0) {
18963            throw new IllegalArgumentException("Can't stop primary user " + userId);
18964        }
18965        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18966        synchronized (this) {
18967            return stopUserLocked(userId, callback);
18968        }
18969    }
18970
18971    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18972        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18973        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18974            return ActivityManager.USER_OP_IS_CURRENT;
18975        }
18976
18977        final UserStartedState uss = mStartedUsers.get(userId);
18978        if (uss == null) {
18979            // User is not started, nothing to do...  but we do need to
18980            // callback if requested.
18981            if (callback != null) {
18982                mHandler.post(new Runnable() {
18983                    @Override
18984                    public void run() {
18985                        try {
18986                            callback.userStopped(userId);
18987                        } catch (RemoteException e) {
18988                        }
18989                    }
18990                });
18991            }
18992            return ActivityManager.USER_OP_SUCCESS;
18993        }
18994
18995        if (callback != null) {
18996            uss.mStopCallbacks.add(callback);
18997        }
18998
18999        if (uss.mState != UserStartedState.STATE_STOPPING
19000                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19001            uss.mState = UserStartedState.STATE_STOPPING;
19002            updateStartedUserArrayLocked();
19003
19004            long ident = Binder.clearCallingIdentity();
19005            try {
19006                // We are going to broadcast ACTION_USER_STOPPING and then
19007                // once that is done send a final ACTION_SHUTDOWN and then
19008                // stop the user.
19009                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19010                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19011                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19012                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19013                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19014                // This is the result receiver for the final shutdown broadcast.
19015                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19016                    @Override
19017                    public void performReceive(Intent intent, int resultCode, String data,
19018                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19019                        finishUserStop(uss);
19020                    }
19021                };
19022                // This is the result receiver for the initial stopping broadcast.
19023                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19024                    @Override
19025                    public void performReceive(Intent intent, int resultCode, String data,
19026                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19027                        // On to the next.
19028                        synchronized (ActivityManagerService.this) {
19029                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19030                                // Whoops, we are being started back up.  Abort, abort!
19031                                return;
19032                            }
19033                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19034                        }
19035                        mBatteryStatsService.noteEvent(
19036                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19037                                Integer.toString(userId), userId);
19038                        mSystemServiceManager.stopUser(userId);
19039                        broadcastIntentLocked(null, null, shutdownIntent,
19040                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19041                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19042                    }
19043                };
19044                // Kick things off.
19045                broadcastIntentLocked(null, null, stoppingIntent,
19046                        null, stoppingReceiver, 0, null, null,
19047                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19048                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19049            } finally {
19050                Binder.restoreCallingIdentity(ident);
19051            }
19052        }
19053
19054        return ActivityManager.USER_OP_SUCCESS;
19055    }
19056
19057    void finishUserStop(UserStartedState uss) {
19058        final int userId = uss.mHandle.getIdentifier();
19059        boolean stopped;
19060        ArrayList<IStopUserCallback> callbacks;
19061        synchronized (this) {
19062            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19063            if (mStartedUsers.get(userId) != uss) {
19064                stopped = false;
19065            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19066                stopped = false;
19067            } else {
19068                stopped = true;
19069                // User can no longer run.
19070                mStartedUsers.remove(userId);
19071                mUserLru.remove(Integer.valueOf(userId));
19072                updateStartedUserArrayLocked();
19073
19074                // Clean up all state and processes associated with the user.
19075                // Kill all the processes for the user.
19076                forceStopUserLocked(userId, "finish user");
19077            }
19078
19079            // Explicitly remove the old information in mRecentTasks.
19080            removeRecentTasksForUserLocked(userId);
19081        }
19082
19083        for (int i=0; i<callbacks.size(); i++) {
19084            try {
19085                if (stopped) callbacks.get(i).userStopped(userId);
19086                else callbacks.get(i).userStopAborted(userId);
19087            } catch (RemoteException e) {
19088            }
19089        }
19090
19091        if (stopped) {
19092            mSystemServiceManager.cleanupUser(userId);
19093            synchronized (this) {
19094                mStackSupervisor.removeUserLocked(userId);
19095            }
19096        }
19097    }
19098
19099    @Override
19100    public UserInfo getCurrentUser() {
19101        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19102                != PackageManager.PERMISSION_GRANTED) && (
19103                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19104                != PackageManager.PERMISSION_GRANTED)) {
19105            String msg = "Permission Denial: getCurrentUser() from pid="
19106                    + Binder.getCallingPid()
19107                    + ", uid=" + Binder.getCallingUid()
19108                    + " requires " + INTERACT_ACROSS_USERS;
19109            Slog.w(TAG, msg);
19110            throw new SecurityException(msg);
19111        }
19112        synchronized (this) {
19113            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19114            return getUserManagerLocked().getUserInfo(userId);
19115        }
19116    }
19117
19118    int getCurrentUserIdLocked() {
19119        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19120    }
19121
19122    @Override
19123    public boolean isUserRunning(int userId, boolean orStopped) {
19124        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19125                != PackageManager.PERMISSION_GRANTED) {
19126            String msg = "Permission Denial: isUserRunning() from pid="
19127                    + Binder.getCallingPid()
19128                    + ", uid=" + Binder.getCallingUid()
19129                    + " requires " + INTERACT_ACROSS_USERS;
19130            Slog.w(TAG, msg);
19131            throw new SecurityException(msg);
19132        }
19133        synchronized (this) {
19134            return isUserRunningLocked(userId, orStopped);
19135        }
19136    }
19137
19138    boolean isUserRunningLocked(int userId, boolean orStopped) {
19139        UserStartedState state = mStartedUsers.get(userId);
19140        if (state == null) {
19141            return false;
19142        }
19143        if (orStopped) {
19144            return true;
19145        }
19146        return state.mState != UserStartedState.STATE_STOPPING
19147                && state.mState != UserStartedState.STATE_SHUTDOWN;
19148    }
19149
19150    @Override
19151    public int[] getRunningUserIds() {
19152        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19153                != PackageManager.PERMISSION_GRANTED) {
19154            String msg = "Permission Denial: isUserRunning() from pid="
19155                    + Binder.getCallingPid()
19156                    + ", uid=" + Binder.getCallingUid()
19157                    + " requires " + INTERACT_ACROSS_USERS;
19158            Slog.w(TAG, msg);
19159            throw new SecurityException(msg);
19160        }
19161        synchronized (this) {
19162            return mStartedUserArray;
19163        }
19164    }
19165
19166    private void updateStartedUserArrayLocked() {
19167        int num = 0;
19168        for (int i=0; i<mStartedUsers.size();  i++) {
19169            UserStartedState uss = mStartedUsers.valueAt(i);
19170            // This list does not include stopping users.
19171            if (uss.mState != UserStartedState.STATE_STOPPING
19172                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19173                num++;
19174            }
19175        }
19176        mStartedUserArray = new int[num];
19177        num = 0;
19178        for (int i=0; i<mStartedUsers.size();  i++) {
19179            UserStartedState uss = mStartedUsers.valueAt(i);
19180            if (uss.mState != UserStartedState.STATE_STOPPING
19181                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19182                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19183                num++;
19184            }
19185        }
19186    }
19187
19188    @Override
19189    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19190        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19191                != PackageManager.PERMISSION_GRANTED) {
19192            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19193                    + Binder.getCallingPid()
19194                    + ", uid=" + Binder.getCallingUid()
19195                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19196            Slog.w(TAG, msg);
19197            throw new SecurityException(msg);
19198        }
19199
19200        mUserSwitchObservers.register(observer);
19201    }
19202
19203    @Override
19204    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19205        mUserSwitchObservers.unregister(observer);
19206    }
19207
19208    private boolean userExists(int userId) {
19209        if (userId == 0) {
19210            return true;
19211        }
19212        UserManagerService ums = getUserManagerLocked();
19213        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19214    }
19215
19216    int[] getUsersLocked() {
19217        UserManagerService ums = getUserManagerLocked();
19218        return ums != null ? ums.getUserIds() : new int[] { 0 };
19219    }
19220
19221    UserManagerService getUserManagerLocked() {
19222        if (mUserManager == null) {
19223            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19224            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19225        }
19226        return mUserManager;
19227    }
19228
19229    private int applyUserId(int uid, int userId) {
19230        return UserHandle.getUid(userId, uid);
19231    }
19232
19233    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19234        if (info == null) return null;
19235        ApplicationInfo newInfo = new ApplicationInfo(info);
19236        newInfo.uid = applyUserId(info.uid, userId);
19237        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19238                + info.packageName;
19239        return newInfo;
19240    }
19241
19242    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19243        if (aInfo == null
19244                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19245            return aInfo;
19246        }
19247
19248        ActivityInfo info = new ActivityInfo(aInfo);
19249        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19250        return info;
19251    }
19252
19253    private final class LocalService extends ActivityManagerInternal {
19254        @Override
19255        public void onWakefulnessChanged(int wakefulness) {
19256            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19257        }
19258
19259        @Override
19260        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19261                String processName, String abiOverride, int uid, Runnable crashHandler) {
19262            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19263                    processName, abiOverride, uid, crashHandler);
19264        }
19265    }
19266
19267    /**
19268     * An implementation of IAppTask, that allows an app to manage its own tasks via
19269     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19270     * only the process that calls getAppTasks() can call the AppTask methods.
19271     */
19272    class AppTaskImpl extends IAppTask.Stub {
19273        private int mTaskId;
19274        private int mCallingUid;
19275
19276        public AppTaskImpl(int taskId, int callingUid) {
19277            mTaskId = taskId;
19278            mCallingUid = callingUid;
19279        }
19280
19281        private void checkCaller() {
19282            if (mCallingUid != Binder.getCallingUid()) {
19283                throw new SecurityException("Caller " + mCallingUid
19284                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19285            }
19286        }
19287
19288        @Override
19289        public void finishAndRemoveTask() {
19290            checkCaller();
19291
19292            synchronized (ActivityManagerService.this) {
19293                long origId = Binder.clearCallingIdentity();
19294                try {
19295                    if (!removeTaskByIdLocked(mTaskId, false)) {
19296                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19297                    }
19298                } finally {
19299                    Binder.restoreCallingIdentity(origId);
19300                }
19301            }
19302        }
19303
19304        @Override
19305        public ActivityManager.RecentTaskInfo getTaskInfo() {
19306            checkCaller();
19307
19308            synchronized (ActivityManagerService.this) {
19309                long origId = Binder.clearCallingIdentity();
19310                try {
19311                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19312                    if (tr == null) {
19313                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19314                    }
19315                    return createRecentTaskInfoFromTaskRecord(tr);
19316                } finally {
19317                    Binder.restoreCallingIdentity(origId);
19318                }
19319            }
19320        }
19321
19322        @Override
19323        public void moveToFront() {
19324            checkCaller();
19325
19326            final TaskRecord tr;
19327            synchronized (ActivityManagerService.this) {
19328                tr = recentTaskForIdLocked(mTaskId);
19329                if (tr == null) {
19330                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19331                }
19332                if (tr.getRootActivity() != null) {
19333                    moveTaskToFrontLocked(tr.taskId, 0, null);
19334                    return;
19335                }
19336            }
19337
19338            startActivityFromRecentsInner(tr.taskId, null);
19339        }
19340
19341        @Override
19342        public int startActivity(IBinder whoThread, String callingPackage,
19343                Intent intent, String resolvedType, Bundle options) {
19344            checkCaller();
19345
19346            int callingUser = UserHandle.getCallingUserId();
19347            TaskRecord tr;
19348            IApplicationThread appThread;
19349            synchronized (ActivityManagerService.this) {
19350                tr = recentTaskForIdLocked(mTaskId);
19351                if (tr == null) {
19352                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19353                }
19354                appThread = ApplicationThreadNative.asInterface(whoThread);
19355                if (appThread == null) {
19356                    throw new IllegalArgumentException("Bad app thread " + appThread);
19357                }
19358            }
19359            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19360                    resolvedType, null, null, null, null, 0, 0, null, null,
19361                    null, options, callingUser, null, tr);
19362        }
19363
19364        @Override
19365        public void setExcludeFromRecents(boolean exclude) {
19366            checkCaller();
19367
19368            synchronized (ActivityManagerService.this) {
19369                long origId = Binder.clearCallingIdentity();
19370                try {
19371                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19372                    if (tr == null) {
19373                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19374                    }
19375                    Intent intent = tr.getBaseIntent();
19376                    if (exclude) {
19377                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19378                    } else {
19379                        intent.setFlags(intent.getFlags()
19380                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19381                    }
19382                } finally {
19383                    Binder.restoreCallingIdentity(origId);
19384                }
19385            }
19386        }
19387    }
19388}
19389