ActivityManagerService.java revision f792e01606b988ab84190217529cca53da8db3f5
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;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import android.view.Display;
61import com.android.internal.R;
62import com.android.internal.annotations.GuardedBy;
63import com.android.internal.app.IAppOpsService;
64import com.android.internal.app.IVoiceInteractor;
65import com.android.internal.app.ProcessMap;
66import com.android.internal.app.ProcessStats;
67import com.android.internal.os.BackgroundThread;
68import com.android.internal.os.BatteryStatsImpl;
69import com.android.internal.os.ProcessCpuTracker;
70import com.android.internal.os.TransferPipe;
71import com.android.internal.os.Zygote;
72import com.android.internal.util.FastPrintWriter;
73import com.android.internal.util.FastXmlSerializer;
74import com.android.internal.util.MemInfoReader;
75import com.android.internal.util.Preconditions;
76import com.android.server.AppOpsService;
77import com.android.server.AttributeCache;
78import com.android.server.IntentResolver;
79import com.android.server.LocalServices;
80import com.android.server.ServiceThread;
81import com.android.server.SystemService;
82import com.android.server.SystemServiceManager;
83import com.android.server.Watchdog;
84import com.android.server.am.ActivityStack.ActivityState;
85import com.android.server.firewall.IntentFirewall;
86import com.android.server.pm.Installer;
87import com.android.server.pm.UserManagerService;
88import com.android.server.statusbar.StatusBarManagerInternal;
89import com.android.server.wm.AppTransition;
90import com.android.server.wm.WindowManagerService;
91import com.google.android.collect.Lists;
92import com.google.android.collect.Maps;
93
94import libcore.io.IoUtils;
95
96import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlPullParserException;
98import org.xmlpull.v1.XmlSerializer;
99
100import android.app.Activity;
101import android.app.ActivityManager;
102import android.app.ActivityManager.RunningTaskInfo;
103import android.app.ActivityManager.StackInfo;
104import android.app.ActivityManagerInternal;
105import android.app.ActivityManagerNative;
106import android.app.ActivityOptions;
107import android.app.ActivityThread;
108import android.app.AlertDialog;
109import android.app.AppGlobals;
110import android.app.ApplicationErrorReport;
111import android.app.Dialog;
112import android.app.IActivityController;
113import android.app.IApplicationThread;
114import android.app.IInstrumentationWatcher;
115import android.app.INotificationManager;
116import android.app.IProcessObserver;
117import android.app.IServiceConnection;
118import android.app.IStopUserCallback;
119import android.app.IUiAutomationConnection;
120import android.app.IUserSwitchObserver;
121import android.app.Instrumentation;
122import android.app.Notification;
123import android.app.NotificationManager;
124import android.app.PendingIntent;
125import android.app.backup.IBackupManager;
126import android.content.ActivityNotFoundException;
127import android.content.BroadcastReceiver;
128import android.content.ClipData;
129import android.content.ComponentCallbacks2;
130import android.content.ComponentName;
131import android.content.ContentProvider;
132import android.content.ContentResolver;
133import android.content.Context;
134import android.content.DialogInterface;
135import android.content.IContentProvider;
136import android.content.IIntentReceiver;
137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.IntentFilter;
140import android.content.IntentSender;
141import android.content.pm.ActivityInfo;
142import android.content.pm.ApplicationInfo;
143import android.content.pm.ConfigurationInfo;
144import android.content.pm.IPackageDataObserver;
145import android.content.pm.IPackageManager;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageManager;
149import android.content.pm.ParceledListSlice;
150import android.content.pm.UserInfo;
151import android.content.pm.PackageManager.NameNotFoundException;
152import android.content.pm.PathPermission;
153import android.content.pm.ProviderInfo;
154import android.content.pm.ResolveInfo;
155import android.content.pm.ServiceInfo;
156import android.content.res.CompatibilityInfo;
157import android.content.res.Configuration;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.DropBoxManager;
166import android.os.Environment;
167import android.os.FactoryTest;
168import android.os.FileObserver;
169import android.os.FileUtils;
170import android.os.Handler;
171import android.os.IBinder;
172import android.os.IPermissionController;
173import android.os.IRemoteCallback;
174import android.os.IUserManager;
175import android.os.Looper;
176import android.os.Message;
177import android.os.Parcel;
178import android.os.ParcelFileDescriptor;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.SELinux;
184import android.os.ServiceManager;
185import android.os.StrictMode;
186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.provider.Settings;
192import android.text.format.DateUtils;
193import android.text.format.Time;
194import android.util.AtomicFile;
195import android.util.EventLog;
196import android.util.Log;
197import android.util.Pair;
198import android.util.PrintWriterPrinter;
199import android.util.Slog;
200import android.util.SparseArray;
201import android.util.TimeUtils;
202import android.util.Xml;
203import android.view.Gravity;
204import android.view.LayoutInflater;
205import android.view.View;
206import android.view.WindowManager;
207
208import dalvik.system.VMRuntime;
209
210import java.io.BufferedInputStream;
211import java.io.BufferedOutputStream;
212import java.io.DataInputStream;
213import java.io.DataOutputStream;
214import java.io.File;
215import java.io.FileDescriptor;
216import java.io.FileInputStream;
217import java.io.FileNotFoundException;
218import java.io.FileOutputStream;
219import java.io.IOException;
220import java.io.InputStreamReader;
221import java.io.PrintWriter;
222import java.io.StringWriter;
223import java.lang.ref.WeakReference;
224import java.util.ArrayList;
225import java.util.Arrays;
226import java.util.Collections;
227import java.util.Comparator;
228import java.util.HashMap;
229import java.util.HashSet;
230import java.util.Iterator;
231import java.util.List;
232import java.util.Locale;
233import java.util.Map;
234import java.util.Set;
235import java.util.concurrent.atomic.AtomicBoolean;
236import java.util.concurrent.atomic.AtomicLong;
237
238public final class ActivityManagerService extends ActivityManagerNative
239        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
240
241    private static final String USER_DATA_DIR = "/data/user/";
242    // File that stores last updated system version and called preboot receivers
243    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
244
245    static final String TAG = "ActivityManager";
246    static final String TAG_MU = "ActivityManagerServiceMU";
247    static final boolean DEBUG = false;
248    static final boolean localLOGV = DEBUG;
249    static final boolean DEBUG_BACKUP = localLOGV || false;
250    static final boolean DEBUG_BROADCAST = localLOGV || false;
251    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
253    static final boolean DEBUG_CLEANUP = localLOGV || false;
254    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
255    static final boolean DEBUG_FOCUS = false;
256    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
257    static final boolean DEBUG_MU = localLOGV || false;
258    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
259    static final boolean DEBUG_LRU = localLOGV || false;
260    static final boolean DEBUG_PAUSE = localLOGV || false;
261    static final boolean DEBUG_POWER = localLOGV || false;
262    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
263    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
264    static final boolean DEBUG_PROCESSES = localLOGV || false;
265    static final boolean DEBUG_PROVIDER = localLOGV || false;
266    static final boolean DEBUG_RESULTS = localLOGV || false;
267    static final boolean DEBUG_SERVICE = localLOGV || false;
268    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
269    static final boolean DEBUG_STACK = localLOGV || false;
270    static final boolean DEBUG_SWITCH = localLOGV || false;
271    static final boolean DEBUG_TASKS = localLOGV || false;
272    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
273    static final boolean DEBUG_TRANSITION = localLOGV || false;
274    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
275    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
276    static final boolean DEBUG_VISBILITY = localLOGV || false;
277    static final boolean DEBUG_PSS = localLOGV || false;
278    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
279    static final boolean DEBUG_RECENTS = localLOGV || false;
280    static final boolean VALIDATE_TOKENS = false;
281    static final boolean SHOW_ACTIVITY_START_TIME = true;
282
283    // Control over CPU and battery monitoring.
284    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
285    static final boolean MONITOR_CPU_USAGE = true;
286    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
287    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
288    static final boolean MONITOR_THREAD_CPU_USAGE = false;
289
290    // The flags that are set for all calls we make to the package manager.
291    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
292
293    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
294
295    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
296
297    // Maximum number recent bitmaps to keep in memory.
298    static final int MAX_RECENT_BITMAPS = 3;
299
300    // Amount of time after a call to stopAppSwitches() during which we will
301    // prevent further untrusted switches from happening.
302    static final long APP_SWITCH_DELAY_TIME = 5*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real.
306    static final int PROC_START_TIMEOUT = 10*1000;
307
308    // How long we wait for a launched process to attach to the activity manager
309    // before we decide it's never going to come up for real, when the process was
310    // started with a wrapper for instrumentation (such as Valgrind) because it
311    // could take much longer than usual.
312    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
313
314    // How long to wait after going idle before forcing apps to GC.
315    static final int GC_TIMEOUT = 5*1000;
316
317    // The minimum amount of time between successive GC requests for a process.
318    static final int GC_MIN_INTERVAL = 60*1000;
319
320    // The minimum amount of time between successive PSS requests for a process.
321    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
322
323    // The minimum amount of time between successive PSS requests for a process
324    // when the request is due to the memory state being lowered.
325    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
326
327    // The rate at which we check for apps using excessive power -- 15 mins.
328    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on wake locks to start killing things.
332    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // The minimum sample duration we will allow before deciding we have
335    // enough data on CPU usage to start killing things.
336    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
337
338    // How long we allow a receiver to run before giving up on it.
339    static final int BROADCAST_FG_TIMEOUT = 10*1000;
340    static final int BROADCAST_BG_TIMEOUT = 60*1000;
341
342    // How long we wait until we timeout on key dispatching.
343    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
344
345    // How long we wait until we timeout on key dispatching during instrumentation.
346    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
347
348    // Amount of time we wait for observers to handle a user switch before
349    // giving up on them and unfreezing the screen.
350    static final int USER_SWITCH_TIMEOUT = 2*1000;
351
352    // Maximum number of users we allow to be running at a time.
353    static final int MAX_RUNNING_USERS = 3;
354
355    // How long to wait in getAssistContextExtras for the activity and foreground services
356    // to respond with the result.
357    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
358
359    // Maximum number of persisted Uri grants a package is allowed
360    static final int MAX_PERSISTED_URI_GRANTS = 128;
361
362    static final int MY_PID = Process.myPid();
363
364    static final String[] EMPTY_STRING_ARRAY = new String[0];
365
366    // How many bytes to write into the dropbox log before truncating
367    static final int DROPBOX_MAX_SIZE = 256 * 1024;
368
369    // Access modes for handleIncomingUser.
370    static final int ALLOW_NON_FULL = 0;
371    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
372    static final int ALLOW_FULL_ONLY = 2;
373
374    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
375
376    // Delay in notifying task stack change listeners (in millis)
377    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
378
379    /** All system services */
380    SystemServiceManager mSystemServiceManager;
381
382    private Installer mInstaller;
383
384    /** Run all ActivityStacks through this */
385    ActivityStackSupervisor mStackSupervisor;
386
387    /** Task stack change listeners. */
388    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
389            new RemoteCallbackList<ITaskStackListener>();
390
391    public IntentFirewall mIntentFirewall;
392
393    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
394    // default actuion automatically.  Important for devices without direct input
395    // devices.
396    private boolean mShowDialogs = true;
397
398    BroadcastQueue mFgBroadcastQueue;
399    BroadcastQueue mBgBroadcastQueue;
400    // Convenient for easy iteration over the queues. Foreground is first
401    // so that dispatch of foreground broadcasts gets precedence.
402    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
403
404    BroadcastQueue broadcastQueueForIntent(Intent intent) {
405        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
406        if (DEBUG_BACKGROUND_BROADCAST) {
407            Slog.i(TAG, "Broadcast intent " + intent + " on "
408                    + (isFg ? "foreground" : "background")
409                    + " queue");
410        }
411        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
412    }
413
414    /**
415     * Activity we have told the window manager to have key focus.
416     */
417    ActivityRecord mFocusedActivity = null;
418
419    /**
420     * List of intents that were used to start the most recent tasks.
421     */
422    ArrayList<TaskRecord> mRecentTasks;
423    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
424
425    /**
426     * For addAppTask: cached of the last activity component that was added.
427     */
428    ComponentName mLastAddedTaskComponent;
429
430    /**
431     * For addAppTask: cached of the last activity uid that was added.
432     */
433    int mLastAddedTaskUid;
434
435    /**
436     * For addAppTask: cached of the last ActivityInfo that was added.
437     */
438    ActivityInfo mLastAddedTaskActivity;
439
440    public class PendingAssistExtras extends Binder implements Runnable {
441        public final ActivityRecord activity;
442        public final Bundle extras;
443        public final Intent intent;
444        public final String hint;
445        public final int userHandle;
446        public boolean haveResult = false;
447        public Bundle result = null;
448        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
449                String _hint, int _userHandle) {
450            activity = _activity;
451            extras = _extras;
452            intent = _intent;
453            hint = _hint;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (this) {
460                haveResult = true;
461                notifyAll();
462            }
463        }
464    }
465
466    final ArrayList<PendingAssistExtras> mPendingAssistExtras
467            = new ArrayList<PendingAssistExtras>();
468
469    /**
470     * Process management.
471     */
472    final ProcessList mProcessList = new ProcessList();
473
474    /**
475     * All of the applications we currently have running organized by name.
476     * The keys are strings of the application package name (as
477     * returned by the package manager), and the keys are ApplicationRecord
478     * objects.
479     */
480    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
481
482    /**
483     * Tracking long-term execution of processes to look for abuse and other
484     * bad app behavior.
485     */
486    final ProcessStatsService mProcessStats;
487
488    /**
489     * The currently running isolated processes.
490     */
491    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
492
493    /**
494     * Counter for assigning isolated process uids, to avoid frequently reusing the
495     * same ones.
496     */
497    int mNextIsolatedProcessUid = 0;
498
499    /**
500     * The currently running heavy-weight process, if any.
501     */
502    ProcessRecord mHeavyWeightProcess = null;
503
504    /**
505     * The last time that various processes have crashed.
506     */
507    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
508
509    /**
510     * Information about a process that is currently marked as bad.
511     */
512    static final class BadProcessInfo {
513        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
514            this.time = time;
515            this.shortMsg = shortMsg;
516            this.longMsg = longMsg;
517            this.stack = stack;
518        }
519
520        final long time;
521        final String shortMsg;
522        final String longMsg;
523        final String stack;
524    }
525
526    /**
527     * Set of applications that we consider to be bad, and will reject
528     * incoming broadcasts from (which the user has no control over).
529     * Processes are added to this set when they have crashed twice within
530     * a minimum amount of time; they are removed from it when they are
531     * later restarted (hopefully due to some user action).  The value is the
532     * time it was added to the list.
533     */
534    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
535
536    /**
537     * All of the processes we currently have running organized by pid.
538     * The keys are the pid running the application.
539     *
540     * <p>NOTE: This object is protected by its own lock, NOT the global
541     * activity manager lock!
542     */
543    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
544
545    /**
546     * All of the processes that have been forced to be foreground.  The key
547     * is the pid of the caller who requested it (we hold a death
548     * link on it).
549     */
550    abstract class ForegroundToken implements IBinder.DeathRecipient {
551        int pid;
552        IBinder token;
553    }
554    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
555
556    /**
557     * List of records for processes that someone had tried to start before the
558     * system was ready.  We don't start them at that point, but ensure they
559     * are started by the time booting is complete.
560     */
561    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
562
563    /**
564     * List of persistent applications that are in the process
565     * of being started.
566     */
567    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Processes that are being forcibly torn down.
571     */
572    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
573
574    /**
575     * List of running applications, sorted by recent usage.
576     * The first entry in the list is the least recently used.
577     */
578    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
579
580    /**
581     * Where in mLruProcesses that the processes hosting activities start.
582     */
583    int mLruProcessActivityStart = 0;
584
585    /**
586     * Where in mLruProcesses that the processes hosting services start.
587     * This is after (lower index) than mLruProcessesActivityStart.
588     */
589    int mLruProcessServiceStart = 0;
590
591    /**
592     * List of processes that should gc as soon as things are idle.
593     */
594    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
595
596    /**
597     * Processes we want to collect PSS data from.
598     */
599    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
600
601    /**
602     * Last time we requested PSS data of all processes.
603     */
604    long mLastFullPssTime = SystemClock.uptimeMillis();
605
606    /**
607     * If set, the next time we collect PSS data we should do a full collection
608     * with data from native processes and the kernel.
609     */
610    boolean mFullPssPending = false;
611
612    /**
613     * This is the process holding what we currently consider to be
614     * the "home" activity.
615     */
616    ProcessRecord mHomeProcess;
617
618    /**
619     * This is the process holding the activity the user last visited that
620     * is in a different process from the one they are currently in.
621     */
622    ProcessRecord mPreviousProcess;
623
624    /**
625     * The time at which the previous process was last visible.
626     */
627    long mPreviousProcessVisibleTime;
628
629    /**
630     * Which uses have been started, so are allowed to run code.
631     */
632    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
633
634    /**
635     * LRU list of history of current users.  Most recently current is at the end.
636     */
637    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
638
639    /**
640     * Constant array of the users that are currently started.
641     */
642    int[] mStartedUserArray = new int[] { 0 };
643
644    /**
645     * Registered observers of the user switching mechanics.
646     */
647    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
648            = new RemoteCallbackList<IUserSwitchObserver>();
649
650    /**
651     * Currently active user switch.
652     */
653    Object mCurUserSwitchCallback;
654
655    /**
656     * Packages that the user has asked to have run in screen size
657     * compatibility mode instead of filling the screen.
658     */
659    final CompatModePackages mCompatModePackages;
660
661    /**
662     * Set of IntentSenderRecord objects that are currently active.
663     */
664    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
665            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
666
667    /**
668     * Fingerprints (hashCode()) of stack traces that we've
669     * already logged DropBox entries for.  Guarded by itself.  If
670     * something (rogue user app) forces this over
671     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
672     */
673    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
674    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
675
676    /**
677     * Strict Mode background batched logging state.
678     *
679     * The string buffer is guarded by itself, and its lock is also
680     * used to determine if another batched write is already
681     * in-flight.
682     */
683    private final StringBuilder mStrictModeBuffer = new StringBuilder();
684
685    /**
686     * Keeps track of all IIntentReceivers that have been registered for
687     * broadcasts.  Hash keys are the receiver IBinder, hash value is
688     * a ReceiverList.
689     */
690    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
691            new HashMap<IBinder, ReceiverList>();
692
693    /**
694     * Resolver for broadcast intents to registered receivers.
695     * Holds BroadcastFilter (subclass of IntentFilter).
696     */
697    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
698            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
699        @Override
700        protected boolean allowFilterResult(
701                BroadcastFilter filter, List<BroadcastFilter> dest) {
702            IBinder target = filter.receiverList.receiver.asBinder();
703            for (int i=dest.size()-1; i>=0; i--) {
704                if (dest.get(i).receiverList.receiver.asBinder() == target) {
705                    return false;
706                }
707            }
708            return true;
709        }
710
711        @Override
712        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
713            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
714                    || userId == filter.owningUserId) {
715                return super.newResult(filter, match, userId);
716            }
717            return null;
718        }
719
720        @Override
721        protected BroadcastFilter[] newArray(int size) {
722            return new BroadcastFilter[size];
723        }
724
725        @Override
726        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
727            return packageName.equals(filter.packageName);
728        }
729    };
730
731    /**
732     * State of all active sticky broadcasts per user.  Keys are the action of the
733     * sticky Intent, values are an ArrayList of all broadcasted intents with
734     * that action (which should usually be one).  The SparseArray is keyed
735     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
736     * for stickies that are sent to all users.
737     */
738    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
739            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
740
741    final ActiveServices mServices;
742
743    final static class Association {
744        final int mSourceUid;
745        final String mSourceProcess;
746        final int mTargetUid;
747        final ComponentName mTargetComponent;
748        final String mTargetProcess;
749
750        int mCount;
751        long mTime;
752
753        int mNesting;
754        long mStartTime;
755
756        Association(int sourceUid, String sourceProcess, int targetUid,
757                ComponentName targetComponent, String targetProcess) {
758            mSourceUid = sourceUid;
759            mSourceProcess = sourceProcess;
760            mTargetUid = targetUid;
761            mTargetComponent = targetComponent;
762            mTargetProcess = targetProcess;
763        }
764    }
765
766    /**
767     * When service association tracking is enabled, this is all of the associations we
768     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
769     * -> association data.
770     */
771    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
772            mAssociations = new SparseArray<>();
773    boolean mTrackingAssociations;
774
775    /**
776     * Backup/restore process management
777     */
778    String mBackupAppName = null;
779    BackupRecord mBackupTarget = null;
780
781    final ProviderMap mProviderMap;
782
783    /**
784     * List of content providers who have clients waiting for them.  The
785     * application is currently being launched and the provider will be
786     * removed from this list once it is published.
787     */
788    final ArrayList<ContentProviderRecord> mLaunchingProviders
789            = new ArrayList<ContentProviderRecord>();
790
791    /**
792     * File storing persisted {@link #mGrantedUriPermissions}.
793     */
794    private final AtomicFile mGrantFile;
795
796    /** XML constants used in {@link #mGrantFile} */
797    private static final String TAG_URI_GRANTS = "uri-grants";
798    private static final String TAG_URI_GRANT = "uri-grant";
799    private static final String ATTR_USER_HANDLE = "userHandle";
800    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
801    private static final String ATTR_TARGET_USER_ID = "targetUserId";
802    private static final String ATTR_SOURCE_PKG = "sourcePkg";
803    private static final String ATTR_TARGET_PKG = "targetPkg";
804    private static final String ATTR_URI = "uri";
805    private static final String ATTR_MODE_FLAGS = "modeFlags";
806    private static final String ATTR_CREATED_TIME = "createdTime";
807    private static final String ATTR_PREFIX = "prefix";
808
809    /**
810     * Global set of specific {@link Uri} permissions that have been granted.
811     * This optimized lookup structure maps from {@link UriPermission#targetUid}
812     * to {@link UriPermission#uri} to {@link UriPermission}.
813     */
814    @GuardedBy("this")
815    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
816            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
817
818    public static class GrantUri {
819        public final int sourceUserId;
820        public final Uri uri;
821        public boolean prefix;
822
823        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
824            this.sourceUserId = sourceUserId;
825            this.uri = uri;
826            this.prefix = prefix;
827        }
828
829        @Override
830        public int hashCode() {
831            int hashCode = 1;
832            hashCode = 31 * hashCode + sourceUserId;
833            hashCode = 31 * hashCode + uri.hashCode();
834            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
835            return hashCode;
836        }
837
838        @Override
839        public boolean equals(Object o) {
840            if (o instanceof GrantUri) {
841                GrantUri other = (GrantUri) o;
842                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
843                        && prefix == other.prefix;
844            }
845            return false;
846        }
847
848        @Override
849        public String toString() {
850            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
851            if (prefix) result += " [prefix]";
852            return result;
853        }
854
855        public String toSafeString() {
856            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
857            if (prefix) result += " [prefix]";
858            return result;
859        }
860
861        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
862            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
863                    ContentProvider.getUriWithoutUserId(uri), false);
864        }
865    }
866
867    CoreSettingsObserver mCoreSettingsObserver;
868
869    /**
870     * Thread-local storage used to carry caller permissions over through
871     * indirect content-provider access.
872     */
873    private class Identity {
874        public final IBinder token;
875        public final int pid;
876        public final int uid;
877
878        Identity(IBinder _token, int _pid, int _uid) {
879            token = _token;
880            pid = _pid;
881            uid = _uid;
882        }
883    }
884
885    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
886
887    /**
888     * All information we have collected about the runtime performance of
889     * any user id that can impact battery performance.
890     */
891    final BatteryStatsService mBatteryStatsService;
892
893    /**
894     * Information about component usage
895     */
896    UsageStatsManagerInternal mUsageStatsService;
897
898    /**
899     * Information about and control over application operations
900     */
901    final AppOpsService mAppOpsService;
902
903    /**
904     * Save recent tasks information across reboots.
905     */
906    final TaskPersister mTaskPersister;
907
908    /**
909     * Current configuration information.  HistoryRecord objects are given
910     * a reference to this object to indicate which configuration they are
911     * currently running in, so this object must be kept immutable.
912     */
913    Configuration mConfiguration = new Configuration();
914
915    /**
916     * Current sequencing integer of the configuration, for skipping old
917     * configurations.
918     */
919    int mConfigurationSeq = 0;
920
921    /**
922     * Hardware-reported OpenGLES version.
923     */
924    final int GL_ES_VERSION;
925
926    /**
927     * List of initialization arguments to pass to all processes when binding applications to them.
928     * For example, references to the commonly used services.
929     */
930    HashMap<String, IBinder> mAppBindArgs;
931
932    /**
933     * Temporary to avoid allocations.  Protected by main lock.
934     */
935    final StringBuilder mStringBuilder = new StringBuilder(256);
936
937    /**
938     * Used to control how we initialize the service.
939     */
940    ComponentName mTopComponent;
941    String mTopAction = Intent.ACTION_MAIN;
942    String mTopData;
943    boolean mProcessesReady = false;
944    boolean mSystemReady = false;
945    boolean mBooting = false;
946    boolean mCallFinishBooting = false;
947    boolean mBootAnimationComplete = false;
948    boolean mWaitingUpdate = false;
949    boolean mDidUpdate = false;
950    boolean mOnBattery = false;
951    boolean mLaunchWarningShown = false;
952
953    Context mContext;
954
955    int mFactoryTest;
956
957    boolean mCheckedForSetup;
958
959    /**
960     * The time at which we will allow normal application switches again,
961     * after a call to {@link #stopAppSwitches()}.
962     */
963    long mAppSwitchesAllowedTime;
964
965    /**
966     * This is set to true after the first switch after mAppSwitchesAllowedTime
967     * is set; any switches after that will clear the time.
968     */
969    boolean mDidAppSwitch;
970
971    /**
972     * Last time (in realtime) at which we checked for power usage.
973     */
974    long mLastPowerCheckRealtime;
975
976    /**
977     * Last time (in uptime) at which we checked for power usage.
978     */
979    long mLastPowerCheckUptime;
980
981    /**
982     * Set while we are wanting to sleep, to prevent any
983     * activities from being started/resumed.
984     */
985    private boolean mSleeping = false;
986
987    /**
988     * Set while we are running a voice interaction.  This overrides
989     * sleeping while it is active.
990     */
991    private boolean mRunningVoice = false;
992
993    /**
994     * State of external calls telling us if the device is awake or asleep.
995     */
996    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
997
998    static final int LOCK_SCREEN_HIDDEN = 0;
999    static final int LOCK_SCREEN_LEAVING = 1;
1000    static final int LOCK_SCREEN_SHOWN = 2;
1001    /**
1002     * State of external call telling us if the lock screen is shown.
1003     */
1004    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1005
1006    /**
1007     * Set if we are shutting down the system, similar to sleeping.
1008     */
1009    boolean mShuttingDown = false;
1010
1011    /**
1012     * Current sequence id for oom_adj computation traversal.
1013     */
1014    int mAdjSeq = 0;
1015
1016    /**
1017     * Current sequence id for process LRU updating.
1018     */
1019    int mLruSeq = 0;
1020
1021    /**
1022     * Keep track of the non-cached/empty process we last found, to help
1023     * determine how to distribute cached/empty processes next time.
1024     */
1025    int mNumNonCachedProcs = 0;
1026
1027    /**
1028     * Keep track of the number of cached hidden procs, to balance oom adj
1029     * distribution between those and empty procs.
1030     */
1031    int mNumCachedHiddenProcs = 0;
1032
1033    /**
1034     * Keep track of the number of service processes we last found, to
1035     * determine on the next iteration which should be B services.
1036     */
1037    int mNumServiceProcs = 0;
1038    int mNewNumAServiceProcs = 0;
1039    int mNewNumServiceProcs = 0;
1040
1041    /**
1042     * Allow the current computed overall memory level of the system to go down?
1043     * This is set to false when we are killing processes for reasons other than
1044     * memory management, so that the now smaller process list will not be taken as
1045     * an indication that memory is tighter.
1046     */
1047    boolean mAllowLowerMemLevel = false;
1048
1049    /**
1050     * The last computed memory level, for holding when we are in a state that
1051     * processes are going away for other reasons.
1052     */
1053    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1054
1055    /**
1056     * The last total number of process we have, to determine if changes actually look
1057     * like a shrinking number of process due to lower RAM.
1058     */
1059    int mLastNumProcesses;
1060
1061    /**
1062     * The uptime of the last time we performed idle maintenance.
1063     */
1064    long mLastIdleTime = SystemClock.uptimeMillis();
1065
1066    /**
1067     * Total time spent with RAM that has been added in the past since the last idle time.
1068     */
1069    long mLowRamTimeSinceLastIdle = 0;
1070
1071    /**
1072     * If RAM is currently low, when that horrible situation started.
1073     */
1074    long mLowRamStartTime = 0;
1075
1076    /**
1077     * For reporting to battery stats the current top application.
1078     */
1079    private String mCurResumedPackage = null;
1080    private int mCurResumedUid = -1;
1081
1082    /**
1083     * For reporting to battery stats the apps currently running foreground
1084     * service.  The ProcessMap is package/uid tuples; each of these contain
1085     * an array of the currently foreground processes.
1086     */
1087    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1088            = new ProcessMap<ArrayList<ProcessRecord>>();
1089
1090    /**
1091     * This is set if we had to do a delayed dexopt of an app before launching
1092     * it, to increase the ANR timeouts in that case.
1093     */
1094    boolean mDidDexOpt;
1095
1096    /**
1097     * Set if the systemServer made a call to enterSafeMode.
1098     */
1099    boolean mSafeMode;
1100
1101    /**
1102     * If true, we are running under a test environment so will sample PSS from processes
1103     * much more rapidly to try to collect better data when the tests are rapidly
1104     * running through apps.
1105     */
1106    boolean mTestPssMode = false;
1107
1108    String mDebugApp = null;
1109    boolean mWaitForDebugger = false;
1110    boolean mDebugTransient = false;
1111    String mOrigDebugApp = null;
1112    boolean mOrigWaitForDebugger = false;
1113    boolean mAlwaysFinishActivities = false;
1114    IActivityController mController = null;
1115    String mProfileApp = null;
1116    ProcessRecord mProfileProc = null;
1117    String mProfileFile;
1118    ParcelFileDescriptor mProfileFd;
1119    int mSamplingInterval = 0;
1120    boolean mAutoStopProfiler = false;
1121    int mProfileType = 0;
1122    String mOpenGlTraceApp = null;
1123
1124    final long[] mTmpLong = new long[1];
1125
1126    static class ProcessChangeItem {
1127        static final int CHANGE_ACTIVITIES = 1<<0;
1128        static final int CHANGE_PROCESS_STATE = 1<<1;
1129        int changes;
1130        int uid;
1131        int pid;
1132        int processState;
1133        boolean foregroundActivities;
1134    }
1135
1136    final RemoteCallbackList<IProcessObserver> mProcessObservers
1137            = new RemoteCallbackList<IProcessObserver>();
1138    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1139
1140    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1141            = new ArrayList<ProcessChangeItem>();
1142    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1143            = new ArrayList<ProcessChangeItem>();
1144
1145    /**
1146     * Runtime CPU use collection thread.  This object's lock is used to
1147     * perform synchronization with the thread (notifying it to run).
1148     */
1149    final Thread mProcessCpuThread;
1150
1151    /**
1152     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1153     * Must acquire this object's lock when accessing it.
1154     * NOTE: this lock will be held while doing long operations (trawling
1155     * through all processes in /proc), so it should never be acquired by
1156     * any critical paths such as when holding the main activity manager lock.
1157     */
1158    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1159            MONITOR_THREAD_CPU_USAGE);
1160    final AtomicLong mLastCpuTime = new AtomicLong(0);
1161    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1162
1163    long mLastWriteTime = 0;
1164
1165    /**
1166     * Used to retain an update lock when the foreground activity is in
1167     * immersive mode.
1168     */
1169    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1170
1171    /**
1172     * Set to true after the system has finished booting.
1173     */
1174    boolean mBooted = false;
1175
1176    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1177    int mProcessLimitOverride = -1;
1178
1179    WindowManagerService mWindowManager;
1180
1181    final ActivityThread mSystemThread;
1182
1183    // Holds the current foreground user's id
1184    int mCurrentUserId = 0;
1185    // Holds the target user's id during a user switch
1186    int mTargetUserId = UserHandle.USER_NULL;
1187    // If there are multiple profiles for the current user, their ids are here
1188    // Currently only the primary user can have managed profiles
1189    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1190
1191    /**
1192     * Mapping from each known user ID to the profile group ID it is associated with.
1193     */
1194    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1195
1196    private UserManagerService mUserManager;
1197
1198    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1199        final ProcessRecord mApp;
1200        final int mPid;
1201        final IApplicationThread mAppThread;
1202
1203        AppDeathRecipient(ProcessRecord app, int pid,
1204                IApplicationThread thread) {
1205            if (localLOGV) Slog.v(
1206                TAG, "New death recipient " + this
1207                + " for thread " + thread.asBinder());
1208            mApp = app;
1209            mPid = pid;
1210            mAppThread = thread;
1211        }
1212
1213        @Override
1214        public void binderDied() {
1215            if (localLOGV) Slog.v(
1216                TAG, "Death received in " + this
1217                + " for thread " + mAppThread.asBinder());
1218            synchronized(ActivityManagerService.this) {
1219                appDiedLocked(mApp, mPid, mAppThread);
1220            }
1221        }
1222    }
1223
1224    static final int SHOW_ERROR_MSG = 1;
1225    static final int SHOW_NOT_RESPONDING_MSG = 2;
1226    static final int SHOW_FACTORY_ERROR_MSG = 3;
1227    static final int UPDATE_CONFIGURATION_MSG = 4;
1228    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1229    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1230    static final int SERVICE_TIMEOUT_MSG = 12;
1231    static final int UPDATE_TIME_ZONE = 13;
1232    static final int SHOW_UID_ERROR_MSG = 14;
1233    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1234    static final int PROC_START_TIMEOUT_MSG = 20;
1235    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1236    static final int KILL_APPLICATION_MSG = 22;
1237    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1238    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1239    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1240    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1241    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1242    static final int CLEAR_DNS_CACHE_MSG = 28;
1243    static final int UPDATE_HTTP_PROXY_MSG = 29;
1244    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1245    static final int DISPATCH_PROCESSES_CHANGED = 31;
1246    static final int DISPATCH_PROCESS_DIED = 32;
1247    static final int REPORT_MEM_USAGE_MSG = 33;
1248    static final int REPORT_USER_SWITCH_MSG = 34;
1249    static final int CONTINUE_USER_SWITCH_MSG = 35;
1250    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1251    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1252    static final int PERSIST_URI_GRANTS_MSG = 38;
1253    static final int REQUEST_ALL_PSS_MSG = 39;
1254    static final int START_PROFILES_MSG = 40;
1255    static final int UPDATE_TIME = 41;
1256    static final int SYSTEM_USER_START_MSG = 42;
1257    static final int SYSTEM_USER_CURRENT_MSG = 43;
1258    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1259    static final int FINISH_BOOTING_MSG = 45;
1260    static final int START_USER_SWITCH_MSG = 46;
1261    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1262    static final int DISMISS_DIALOG_MSG = 48;
1263    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1264    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1265
1266    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1267    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1268    static final int FIRST_COMPAT_MODE_MSG = 300;
1269    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1270
1271    CompatModeDialog mCompatModeDialog;
1272    long mLastMemUsageReportTime = 0;
1273
1274    /**
1275     * Flag whether the current user is a "monkey", i.e. whether
1276     * the UI is driven by a UI automation tool.
1277     */
1278    private boolean mUserIsMonkey;
1279
1280    /** Flag whether the device has a Recents UI */
1281    boolean mHasRecents;
1282
1283    /** The dimensions of the thumbnails in the Recents UI. */
1284    int mThumbnailWidth;
1285    int mThumbnailHeight;
1286
1287    final ServiceThread mHandlerThread;
1288    final MainHandler mHandler;
1289
1290    final class MainHandler extends Handler {
1291        public MainHandler(Looper looper) {
1292            super(looper, null, true);
1293        }
1294
1295        @Override
1296        public void handleMessage(Message msg) {
1297            switch (msg.what) {
1298            case SHOW_ERROR_MSG: {
1299                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1300                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1301                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord proc = (ProcessRecord)data.get("app");
1304                    AppErrorResult res = (AppErrorResult) data.get("result");
1305                    if (proc != null && proc.crashDialog != null) {
1306                        Slog.e(TAG, "App already has crash dialog: " + proc);
1307                        if (res != null) {
1308                            res.set(0);
1309                        }
1310                        return;
1311                    }
1312                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1313                            >= Process.FIRST_APPLICATION_UID
1314                            && proc.pid != MY_PID);
1315                    for (int userId : mCurrentProfileIds) {
1316                        isBackground &= (proc.userId != userId);
1317                    }
1318                    if (isBackground && !showBackground) {
1319                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1320                        if (res != null) {
1321                            res.set(0);
1322                        }
1323                        return;
1324                    }
1325                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1326                        Dialog d = new AppErrorDialog(mContext,
1327                                ActivityManagerService.this, res, proc);
1328                        d.show();
1329                        proc.crashDialog = d;
1330                    } else {
1331                        // The device is asleep, so just pretend that the user
1332                        // saw a crash dialog and hit "force quit".
1333                        if (res != null) {
1334                            res.set(0);
1335                        }
1336                    }
1337                }
1338
1339                ensureBootCompleted();
1340            } break;
1341            case SHOW_NOT_RESPONDING_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1344                    ProcessRecord proc = (ProcessRecord)data.get("app");
1345                    if (proc != null && proc.anrDialog != null) {
1346                        Slog.e(TAG, "App already has anr dialog: " + proc);
1347                        return;
1348                    }
1349
1350                    Intent intent = new Intent("android.intent.action.ANR");
1351                    if (!mProcessesReady) {
1352                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1353                                | Intent.FLAG_RECEIVER_FOREGROUND);
1354                    }
1355                    broadcastIntentLocked(null, null, intent,
1356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1357                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1358
1359                    if (mShowDialogs) {
1360                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1361                                mContext, proc, (ActivityRecord)data.get("activity"),
1362                                msg.arg1 != 0);
1363                        d.show();
1364                        proc.anrDialog = d;
1365                    } else {
1366                        // Just kill the app if there is no dialog to be shown.
1367                        killAppAtUsersRequest(proc, null);
1368                    }
1369                }
1370
1371                ensureBootCompleted();
1372            } break;
1373            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1374                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1375                synchronized (ActivityManagerService.this) {
1376                    ProcessRecord proc = (ProcessRecord) data.get("app");
1377                    if (proc == null) {
1378                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1379                        break;
1380                    }
1381                    if (proc.crashDialog != null) {
1382                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1383                        return;
1384                    }
1385                    AppErrorResult res = (AppErrorResult) data.get("result");
1386                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1387                        Dialog d = new StrictModeViolationDialog(mContext,
1388                                ActivityManagerService.this, res, proc);
1389                        d.show();
1390                        proc.crashDialog = d;
1391                    } else {
1392                        // The device is asleep, so just pretend that the user
1393                        // saw a crash dialog and hit "force quit".
1394                        res.set(0);
1395                    }
1396                }
1397                ensureBootCompleted();
1398            } break;
1399            case SHOW_FACTORY_ERROR_MSG: {
1400                Dialog d = new FactoryErrorDialog(
1401                    mContext, msg.getData().getCharSequence("msg"));
1402                d.show();
1403                ensureBootCompleted();
1404            } break;
1405            case UPDATE_CONFIGURATION_MSG: {
1406                final ContentResolver resolver = mContext.getContentResolver();
1407                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1408            } break;
1409            case GC_BACKGROUND_PROCESSES_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    performAppGcsIfAppropriateLocked();
1412                }
1413            } break;
1414            case WAIT_FOR_DEBUGGER_MSG: {
1415                synchronized (ActivityManagerService.this) {
1416                    ProcessRecord app = (ProcessRecord)msg.obj;
1417                    if (msg.arg1 != 0) {
1418                        if (!app.waitedForDebugger) {
1419                            Dialog d = new AppWaitingForDebuggerDialog(
1420                                    ActivityManagerService.this,
1421                                    mContext, app);
1422                            app.waitDialog = d;
1423                            app.waitedForDebugger = true;
1424                            d.show();
1425                        }
1426                    } else {
1427                        if (app.waitDialog != null) {
1428                            app.waitDialog.dismiss();
1429                            app.waitDialog = null;
1430                        }
1431                    }
1432                }
1433            } break;
1434            case SERVICE_TIMEOUT_MSG: {
1435                if (mDidDexOpt) {
1436                    mDidDexOpt = false;
1437                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1438                    nmsg.obj = msg.obj;
1439                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1440                    return;
1441                }
1442                mServices.serviceTimeout((ProcessRecord)msg.obj);
1443            } break;
1444            case UPDATE_TIME_ZONE: {
1445                synchronized (ActivityManagerService.this) {
1446                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1447                        ProcessRecord r = mLruProcesses.get(i);
1448                        if (r.thread != null) {
1449                            try {
1450                                r.thread.updateTimeZone();
1451                            } catch (RemoteException ex) {
1452                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1453                            }
1454                        }
1455                    }
1456                }
1457            } break;
1458            case CLEAR_DNS_CACHE_MSG: {
1459                synchronized (ActivityManagerService.this) {
1460                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1461                        ProcessRecord r = mLruProcesses.get(i);
1462                        if (r.thread != null) {
1463                            try {
1464                                r.thread.clearDnsCache();
1465                            } catch (RemoteException ex) {
1466                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1467                            }
1468                        }
1469                    }
1470                }
1471            } break;
1472            case UPDATE_HTTP_PROXY_MSG: {
1473                ProxyInfo proxy = (ProxyInfo)msg.obj;
1474                String host = "";
1475                String port = "";
1476                String exclList = "";
1477                Uri pacFileUrl = Uri.EMPTY;
1478                if (proxy != null) {
1479                    host = proxy.getHost();
1480                    port = Integer.toString(proxy.getPort());
1481                    exclList = proxy.getExclusionListAsString();
1482                    pacFileUrl = proxy.getPacFileUrl();
1483                }
1484                synchronized (ActivityManagerService.this) {
1485                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1486                        ProcessRecord r = mLruProcesses.get(i);
1487                        if (r.thread != null) {
1488                            try {
1489                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1490                            } catch (RemoteException ex) {
1491                                Slog.w(TAG, "Failed to update http proxy for: " +
1492                                        r.info.processName);
1493                            }
1494                        }
1495                    }
1496                }
1497            } break;
1498            case SHOW_UID_ERROR_MSG: {
1499                if (mShowDialogs) {
1500                    AlertDialog d = new BaseErrorDialog(mContext);
1501                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1502                    d.setCancelable(false);
1503                    d.setTitle(mContext.getText(R.string.android_system_label));
1504                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1505                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1506                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1507                    d.show();
1508                }
1509            } break;
1510            case SHOW_FINGERPRINT_ERROR_MSG: {
1511                if (mShowDialogs) {
1512                    AlertDialog d = new BaseErrorDialog(mContext);
1513                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1514                    d.setCancelable(false);
1515                    d.setTitle(mContext.getText(R.string.android_system_label));
1516                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1517                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1518                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1519                    d.show();
1520                }
1521            } break;
1522            case PROC_START_TIMEOUT_MSG: {
1523                if (mDidDexOpt) {
1524                    mDidDexOpt = false;
1525                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1526                    nmsg.obj = msg.obj;
1527                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1528                    return;
1529                }
1530                ProcessRecord app = (ProcessRecord)msg.obj;
1531                synchronized (ActivityManagerService.this) {
1532                    processStartTimedOutLocked(app);
1533                }
1534            } break;
1535            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1538                }
1539            } break;
1540            case KILL_APPLICATION_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    int appid = msg.arg1;
1543                    boolean restart = (msg.arg2 == 1);
1544                    Bundle bundle = (Bundle)msg.obj;
1545                    String pkg = bundle.getString("pkg");
1546                    String reason = bundle.getString("reason");
1547                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1548                            false, UserHandle.USER_ALL, reason);
1549                }
1550            } break;
1551            case FINALIZE_PENDING_INTENT_MSG: {
1552                ((PendingIntentRecord)msg.obj).completeFinalize();
1553            } break;
1554            case POST_HEAVY_NOTIFICATION_MSG: {
1555                INotificationManager inm = NotificationManager.getService();
1556                if (inm == null) {
1557                    return;
1558                }
1559
1560                ActivityRecord root = (ActivityRecord)msg.obj;
1561                ProcessRecord process = root.app;
1562                if (process == null) {
1563                    return;
1564                }
1565
1566                try {
1567                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1568                    String text = mContext.getString(R.string.heavy_weight_notification,
1569                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1570                    Notification notification = new Notification();
1571                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1572                    notification.when = 0;
1573                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1574                    notification.tickerText = text;
1575                    notification.defaults = 0; // please be quiet
1576                    notification.sound = null;
1577                    notification.vibrate = null;
1578                    notification.color = mContext.getResources().getColor(
1579                            com.android.internal.R.color.system_notification_accent_color);
1580                    notification.setLatestEventInfo(context, text,
1581                            mContext.getText(R.string.heavy_weight_notification_detail),
1582                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1583                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1584                                    new UserHandle(root.userId)));
1585
1586                    try {
1587                        int[] outId = new int[1];
1588                        inm.enqueueNotificationWithTag("android", "android", null,
1589                                R.string.heavy_weight_notification,
1590                                notification, outId, root.userId);
1591                    } catch (RuntimeException e) {
1592                        Slog.w(ActivityManagerService.TAG,
1593                                "Error showing notification for heavy-weight app", e);
1594                    } catch (RemoteException e) {
1595                    }
1596                } catch (NameNotFoundException e) {
1597                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1598                }
1599            } break;
1600            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1601                INotificationManager inm = NotificationManager.getService();
1602                if (inm == null) {
1603                    return;
1604                }
1605                try {
1606                    inm.cancelNotificationWithTag("android", null,
1607                            R.string.heavy_weight_notification,  msg.arg1);
1608                } catch (RuntimeException e) {
1609                    Slog.w(ActivityManagerService.TAG,
1610                            "Error canceling notification for service", e);
1611                } catch (RemoteException e) {
1612                }
1613            } break;
1614            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1615                synchronized (ActivityManagerService.this) {
1616                    checkExcessivePowerUsageLocked(true);
1617                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1618                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1619                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1620                }
1621            } break;
1622            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    ActivityRecord ar = (ActivityRecord)msg.obj;
1625                    if (mCompatModeDialog != null) {
1626                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1627                                ar.info.applicationInfo.packageName)) {
1628                            return;
1629                        }
1630                        mCompatModeDialog.dismiss();
1631                        mCompatModeDialog = null;
1632                    }
1633                    if (ar != null && false) {
1634                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1635                                ar.packageName)) {
1636                            int mode = mCompatModePackages.computeCompatModeLocked(
1637                                    ar.info.applicationInfo);
1638                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1639                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1640                                mCompatModeDialog = new CompatModeDialog(
1641                                        ActivityManagerService.this, mContext,
1642                                        ar.info.applicationInfo);
1643                                mCompatModeDialog.show();
1644                            }
1645                        }
1646                    }
1647                }
1648                break;
1649            }
1650            case DISPATCH_PROCESSES_CHANGED: {
1651                dispatchProcessesChanged();
1652                break;
1653            }
1654            case DISPATCH_PROCESS_DIED: {
1655                final int pid = msg.arg1;
1656                final int uid = msg.arg2;
1657                dispatchProcessDied(pid, uid);
1658                break;
1659            }
1660            case REPORT_MEM_USAGE_MSG: {
1661                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1662                Thread thread = new Thread() {
1663                    @Override public void run() {
1664                        reportMemUsage(memInfos);
1665                    }
1666                };
1667                thread.start();
1668                break;
1669            }
1670            case START_USER_SWITCH_MSG: {
1671                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1672                break;
1673            }
1674            case REPORT_USER_SWITCH_MSG: {
1675                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1676                break;
1677            }
1678            case CONTINUE_USER_SWITCH_MSG: {
1679                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1680                break;
1681            }
1682            case USER_SWITCH_TIMEOUT_MSG: {
1683                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1684                break;
1685            }
1686            case IMMERSIVE_MODE_LOCK_MSG: {
1687                final boolean nextState = (msg.arg1 != 0);
1688                if (mUpdateLock.isHeld() != nextState) {
1689                    if (DEBUG_IMMERSIVE) {
1690                        final ActivityRecord r = (ActivityRecord) msg.obj;
1691                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1692                    }
1693                    if (nextState) {
1694                        mUpdateLock.acquire();
1695                    } else {
1696                        mUpdateLock.release();
1697                    }
1698                }
1699                break;
1700            }
1701            case PERSIST_URI_GRANTS_MSG: {
1702                writeGrantedUriPermissions();
1703                break;
1704            }
1705            case REQUEST_ALL_PSS_MSG: {
1706                synchronized (ActivityManagerService.this) {
1707                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1708                }
1709                break;
1710            }
1711            case START_PROFILES_MSG: {
1712                synchronized (ActivityManagerService.this) {
1713                    startProfilesLocked();
1714                }
1715                break;
1716            }
1717            case UPDATE_TIME: {
1718                synchronized (ActivityManagerService.this) {
1719                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1720                        ProcessRecord r = mLruProcesses.get(i);
1721                        if (r.thread != null) {
1722                            try {
1723                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1724                            } catch (RemoteException ex) {
1725                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1726                            }
1727                        }
1728                    }
1729                }
1730                break;
1731            }
1732            case SYSTEM_USER_START_MSG: {
1733                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1734                        Integer.toString(msg.arg1), msg.arg1);
1735                mSystemServiceManager.startUser(msg.arg1);
1736                break;
1737            }
1738            case SYSTEM_USER_CURRENT_MSG: {
1739                mBatteryStatsService.noteEvent(
1740                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1741                        Integer.toString(msg.arg2), msg.arg2);
1742                mBatteryStatsService.noteEvent(
1743                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1744                        Integer.toString(msg.arg1), msg.arg1);
1745                mSystemServiceManager.switchUser(msg.arg1);
1746                break;
1747            }
1748            case ENTER_ANIMATION_COMPLETE_MSG: {
1749                synchronized (ActivityManagerService.this) {
1750                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1751                    if (r != null && r.app != null && r.app.thread != null) {
1752                        try {
1753                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1754                        } catch (RemoteException e) {
1755                        }
1756                    }
1757                }
1758                break;
1759            }
1760            case FINISH_BOOTING_MSG: {
1761                if (msg.arg1 != 0) {
1762                    finishBooting();
1763                }
1764                if (msg.arg2 != 0) {
1765                    enableScreenAfterBoot();
1766                }
1767                break;
1768            }
1769            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1770                try {
1771                    Locale l = (Locale) msg.obj;
1772                    IBinder service = ServiceManager.getService("mount");
1773                    IMountService mountService = IMountService.Stub.asInterface(service);
1774                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1775                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1776                } catch (RemoteException e) {
1777                    Log.e(TAG, "Error storing locale for decryption UI", e);
1778                }
1779                break;
1780            }
1781            case DISMISS_DIALOG_MSG: {
1782                final Dialog d = (Dialog) msg.obj;
1783                d.dismiss();
1784                break;
1785            }
1786            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    int i = mTaskStackListeners.beginBroadcast();
1789                    while (i > 0) {
1790                        i--;
1791                        try {
1792                            // Make a one-way callback to the listener
1793                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1794                        } catch (RemoteException e){
1795                            // Handled by the RemoteCallbackList
1796                        }
1797                    }
1798                    mTaskStackListeners.finishBroadcast();
1799                }
1800                break;
1801            }
1802            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1803                final int uid = msg.arg1;
1804                final byte[] firstPacket = (byte[]) msg.obj;
1805
1806                synchronized (mPidsSelfLocked) {
1807                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1808                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1809                        if (p.uid == uid) {
1810                            try {
1811                                p.thread.notifyCleartextNetwork(firstPacket);
1812                            } catch (RemoteException ignored) {
1813                            }
1814                        }
1815                    }
1816                }
1817                break;
1818            }
1819            }
1820        }
1821    };
1822
1823    static final int COLLECT_PSS_BG_MSG = 1;
1824
1825    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1826        @Override
1827        public void handleMessage(Message msg) {
1828            switch (msg.what) {
1829            case COLLECT_PSS_BG_MSG: {
1830                long start = SystemClock.uptimeMillis();
1831                MemInfoReader memInfo = null;
1832                synchronized (ActivityManagerService.this) {
1833                    if (mFullPssPending) {
1834                        mFullPssPending = false;
1835                        memInfo = new MemInfoReader();
1836                    }
1837                }
1838                if (memInfo != null) {
1839                    updateCpuStatsNow();
1840                    long nativeTotalPss = 0;
1841                    synchronized (mProcessCpuTracker) {
1842                        final int N = mProcessCpuTracker.countStats();
1843                        for (int j=0; j<N; j++) {
1844                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1845                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1846                                // This is definitely an application process; skip it.
1847                                continue;
1848                            }
1849                            synchronized (mPidsSelfLocked) {
1850                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1851                                    // This is one of our own processes; skip it.
1852                                    continue;
1853                                }
1854                            }
1855                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1856                        }
1857                    }
1858                    memInfo.readMemInfo();
1859                    synchronized (ActivityManagerService.this) {
1860                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1861                                + (SystemClock.uptimeMillis()-start) + "ms");
1862                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1863                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1864                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1865                    }
1866                }
1867
1868                int num = 0;
1869                long[] tmp = new long[1];
1870                do {
1871                    ProcessRecord proc;
1872                    int procState;
1873                    int pid;
1874                    long lastPssTime;
1875                    synchronized (ActivityManagerService.this) {
1876                        if (mPendingPssProcesses.size() <= 0) {
1877                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1878                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1879                            mPendingPssProcesses.clear();
1880                            return;
1881                        }
1882                        proc = mPendingPssProcesses.remove(0);
1883                        procState = proc.pssProcState;
1884                        lastPssTime = proc.lastPssTime;
1885                        if (proc.thread != null && procState == proc.setProcState
1886                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1887                                        < SystemClock.uptimeMillis()) {
1888                            pid = proc.pid;
1889                        } else {
1890                            proc = null;
1891                            pid = 0;
1892                        }
1893                    }
1894                    if (proc != null) {
1895                        long pss = Debug.getPss(pid, tmp, null);
1896                        synchronized (ActivityManagerService.this) {
1897                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1898                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1899                                num++;
1900                                recordPssSample(proc, procState, pss, tmp[0],
1901                                        SystemClock.uptimeMillis());
1902                            }
1903                        }
1904                    }
1905                } while (true);
1906            }
1907            }
1908        }
1909    };
1910
1911    public void setSystemProcess() {
1912        try {
1913            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1914            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1915            ServiceManager.addService("meminfo", new MemBinder(this));
1916            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1917            ServiceManager.addService("dbinfo", new DbBinder(this));
1918            if (MONITOR_CPU_USAGE) {
1919                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1920            }
1921            ServiceManager.addService("permission", new PermissionController(this));
1922
1923            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1924                    "android", STOCK_PM_FLAGS);
1925            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1926
1927            synchronized (this) {
1928                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1929                app.persistent = true;
1930                app.pid = MY_PID;
1931                app.maxAdj = ProcessList.SYSTEM_ADJ;
1932                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1933                mProcessNames.put(app.processName, app.uid, app);
1934                synchronized (mPidsSelfLocked) {
1935                    mPidsSelfLocked.put(app.pid, app);
1936                }
1937                updateLruProcessLocked(app, false, null);
1938                updateOomAdjLocked();
1939            }
1940        } catch (PackageManager.NameNotFoundException e) {
1941            throw new RuntimeException(
1942                    "Unable to find android system package", e);
1943        }
1944    }
1945
1946    public void setWindowManager(WindowManagerService wm) {
1947        mWindowManager = wm;
1948        mStackSupervisor.setWindowManager(wm);
1949    }
1950
1951    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1952        mUsageStatsService = usageStatsManager;
1953    }
1954
1955    public void startObservingNativeCrashes() {
1956        final NativeCrashListener ncl = new NativeCrashListener(this);
1957        ncl.start();
1958    }
1959
1960    public IAppOpsService getAppOpsService() {
1961        return mAppOpsService;
1962    }
1963
1964    static class MemBinder extends Binder {
1965        ActivityManagerService mActivityManagerService;
1966        MemBinder(ActivityManagerService activityManagerService) {
1967            mActivityManagerService = activityManagerService;
1968        }
1969
1970        @Override
1971        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1972            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1973                    != PackageManager.PERMISSION_GRANTED) {
1974                pw.println("Permission Denial: can't dump meminfo from from pid="
1975                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1976                        + " without permission " + android.Manifest.permission.DUMP);
1977                return;
1978            }
1979
1980            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1981        }
1982    }
1983
1984    static class GraphicsBinder extends Binder {
1985        ActivityManagerService mActivityManagerService;
1986        GraphicsBinder(ActivityManagerService activityManagerService) {
1987            mActivityManagerService = activityManagerService;
1988        }
1989
1990        @Override
1991        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                    != PackageManager.PERMISSION_GRANTED) {
1994                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1995                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                        + " without permission " + android.Manifest.permission.DUMP);
1997                return;
1998            }
1999
2000            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2001        }
2002    }
2003
2004    static class DbBinder extends Binder {
2005        ActivityManagerService mActivityManagerService;
2006        DbBinder(ActivityManagerService activityManagerService) {
2007            mActivityManagerService = activityManagerService;
2008        }
2009
2010        @Override
2011        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                    != PackageManager.PERMISSION_GRANTED) {
2014                pw.println("Permission Denial: can't dump dbinfo from from pid="
2015                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                        + " without permission " + android.Manifest.permission.DUMP);
2017                return;
2018            }
2019
2020            mActivityManagerService.dumpDbInfo(fd, pw, args);
2021        }
2022    }
2023
2024    static class CpuBinder extends Binder {
2025        ActivityManagerService mActivityManagerService;
2026        CpuBinder(ActivityManagerService activityManagerService) {
2027            mActivityManagerService = activityManagerService;
2028        }
2029
2030        @Override
2031        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                    != PackageManager.PERMISSION_GRANTED) {
2034                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2035                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                        + " without permission " + android.Manifest.permission.DUMP);
2037                return;
2038            }
2039
2040            synchronized (mActivityManagerService.mProcessCpuTracker) {
2041                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2042                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2043                        SystemClock.uptimeMillis()));
2044            }
2045        }
2046    }
2047
2048    public static final class Lifecycle extends SystemService {
2049        private final ActivityManagerService mService;
2050
2051        public Lifecycle(Context context) {
2052            super(context);
2053            mService = new ActivityManagerService(context);
2054        }
2055
2056        @Override
2057        public void onStart() {
2058            mService.start();
2059        }
2060
2061        public ActivityManagerService getService() {
2062            return mService;
2063        }
2064    }
2065
2066    // Note: This method is invoked on the main thread but may need to attach various
2067    // handlers to other threads.  So take care to be explicit about the looper.
2068    public ActivityManagerService(Context systemContext) {
2069        mContext = systemContext;
2070        mFactoryTest = FactoryTest.getMode();
2071        mSystemThread = ActivityThread.currentActivityThread();
2072
2073        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2074
2075        mHandlerThread = new ServiceThread(TAG,
2076                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2077        mHandlerThread.start();
2078        mHandler = new MainHandler(mHandlerThread.getLooper());
2079
2080        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2081                "foreground", BROADCAST_FG_TIMEOUT, false);
2082        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2083                "background", BROADCAST_BG_TIMEOUT, true);
2084        mBroadcastQueues[0] = mFgBroadcastQueue;
2085        mBroadcastQueues[1] = mBgBroadcastQueue;
2086
2087        mServices = new ActiveServices(this);
2088        mProviderMap = new ProviderMap(this);
2089
2090        // TODO: Move creation of battery stats service outside of activity manager service.
2091        File dataDir = Environment.getDataDirectory();
2092        File systemDir = new File(dataDir, "system");
2093        systemDir.mkdirs();
2094        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2095        mBatteryStatsService.getActiveStatistics().readLocked();
2096        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2097        mOnBattery = DEBUG_POWER ? true
2098                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2099        mBatteryStatsService.getActiveStatistics().setCallback(this);
2100
2101        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2102
2103        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2104
2105        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2106
2107        // User 0 is the first and only user that runs at boot.
2108        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2109        mUserLru.add(Integer.valueOf(0));
2110        updateStartedUserArrayLocked();
2111
2112        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2113            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2114
2115        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2116
2117        mConfiguration.setToDefaults();
2118        mConfiguration.locale = Locale.getDefault();
2119
2120        mConfigurationSeq = mConfiguration.seq = 1;
2121        mProcessCpuTracker.init();
2122
2123        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2124        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2125        mStackSupervisor = new ActivityStackSupervisor(this);
2126        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2127
2128        mProcessCpuThread = new Thread("CpuTracker") {
2129            @Override
2130            public void run() {
2131                while (true) {
2132                    try {
2133                        try {
2134                            synchronized(this) {
2135                                final long now = SystemClock.uptimeMillis();
2136                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2137                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2138                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2139                                //        + ", write delay=" + nextWriteDelay);
2140                                if (nextWriteDelay < nextCpuDelay) {
2141                                    nextCpuDelay = nextWriteDelay;
2142                                }
2143                                if (nextCpuDelay > 0) {
2144                                    mProcessCpuMutexFree.set(true);
2145                                    this.wait(nextCpuDelay);
2146                                }
2147                            }
2148                        } catch (InterruptedException e) {
2149                        }
2150                        updateCpuStatsNow();
2151                    } catch (Exception e) {
2152                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2153                    }
2154                }
2155            }
2156        };
2157
2158        Watchdog.getInstance().addMonitor(this);
2159        Watchdog.getInstance().addThread(mHandler);
2160    }
2161
2162    public void setSystemServiceManager(SystemServiceManager mgr) {
2163        mSystemServiceManager = mgr;
2164    }
2165
2166    public void setInstaller(Installer installer) {
2167        mInstaller = installer;
2168    }
2169
2170    private void start() {
2171        Process.removeAllProcessGroups();
2172        mProcessCpuThread.start();
2173
2174        mBatteryStatsService.publish(mContext);
2175        mAppOpsService.publish(mContext);
2176        Slog.d("AppOps", "AppOpsService published");
2177        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2178    }
2179
2180    public void initPowerManagement() {
2181        mStackSupervisor.initPowerManagement();
2182        mBatteryStatsService.initPowerManagement();
2183    }
2184
2185    @Override
2186    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2187            throws RemoteException {
2188        if (code == SYSPROPS_TRANSACTION) {
2189            // We need to tell all apps about the system property change.
2190            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2191            synchronized(this) {
2192                final int NP = mProcessNames.getMap().size();
2193                for (int ip=0; ip<NP; ip++) {
2194                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2195                    final int NA = apps.size();
2196                    for (int ia=0; ia<NA; ia++) {
2197                        ProcessRecord app = apps.valueAt(ia);
2198                        if (app.thread != null) {
2199                            procs.add(app.thread.asBinder());
2200                        }
2201                    }
2202                }
2203            }
2204
2205            int N = procs.size();
2206            for (int i=0; i<N; i++) {
2207                Parcel data2 = Parcel.obtain();
2208                try {
2209                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2210                } catch (RemoteException e) {
2211                }
2212                data2.recycle();
2213            }
2214        }
2215        try {
2216            return super.onTransact(code, data, reply, flags);
2217        } catch (RuntimeException e) {
2218            // The activity manager only throws security exceptions, so let's
2219            // log all others.
2220            if (!(e instanceof SecurityException)) {
2221                Slog.wtf(TAG, "Activity Manager Crash", e);
2222            }
2223            throw e;
2224        }
2225    }
2226
2227    void updateCpuStats() {
2228        final long now = SystemClock.uptimeMillis();
2229        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2230            return;
2231        }
2232        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2233            synchronized (mProcessCpuThread) {
2234                mProcessCpuThread.notify();
2235            }
2236        }
2237    }
2238
2239    void updateCpuStatsNow() {
2240        synchronized (mProcessCpuTracker) {
2241            mProcessCpuMutexFree.set(false);
2242            final long now = SystemClock.uptimeMillis();
2243            boolean haveNewCpuStats = false;
2244
2245            if (MONITOR_CPU_USAGE &&
2246                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2247                mLastCpuTime.set(now);
2248                haveNewCpuStats = true;
2249                mProcessCpuTracker.update();
2250                //Slog.i(TAG, mProcessCpu.printCurrentState());
2251                //Slog.i(TAG, "Total CPU usage: "
2252                //        + mProcessCpu.getTotalCpuPercent() + "%");
2253
2254                // Slog the cpu usage if the property is set.
2255                if ("true".equals(SystemProperties.get("events.cpu"))) {
2256                    int user = mProcessCpuTracker.getLastUserTime();
2257                    int system = mProcessCpuTracker.getLastSystemTime();
2258                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2259                    int irq = mProcessCpuTracker.getLastIrqTime();
2260                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2261                    int idle = mProcessCpuTracker.getLastIdleTime();
2262
2263                    int total = user + system + iowait + irq + softIrq + idle;
2264                    if (total == 0) total = 1;
2265
2266                    EventLog.writeEvent(EventLogTags.CPU,
2267                            ((user+system+iowait+irq+softIrq) * 100) / total,
2268                            (user * 100) / total,
2269                            (system * 100) / total,
2270                            (iowait * 100) / total,
2271                            (irq * 100) / total,
2272                            (softIrq * 100) / total);
2273                }
2274            }
2275
2276            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2277            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2278            synchronized(bstats) {
2279                synchronized(mPidsSelfLocked) {
2280                    if (haveNewCpuStats) {
2281                        if (mOnBattery) {
2282                            int perc = bstats.startAddingCpuLocked();
2283                            int totalUTime = 0;
2284                            int totalSTime = 0;
2285                            final int N = mProcessCpuTracker.countStats();
2286                            for (int i=0; i<N; i++) {
2287                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2288                                if (!st.working) {
2289                                    continue;
2290                                }
2291                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2292                                int otherUTime = (st.rel_utime*perc)/100;
2293                                int otherSTime = (st.rel_stime*perc)/100;
2294                                totalUTime += otherUTime;
2295                                totalSTime += otherSTime;
2296                                if (pr != null) {
2297                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2298                                    if (ps == null || !ps.isActive()) {
2299                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2300                                                pr.info.uid, pr.processName);
2301                                    }
2302                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2303                                            st.rel_stime-otherSTime);
2304                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2305                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2306                                } else {
2307                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2308                                    if (ps == null || !ps.isActive()) {
2309                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2310                                                bstats.mapUid(st.uid), st.name);
2311                                    }
2312                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2313                                            st.rel_stime-otherSTime);
2314                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2315                                }
2316                            }
2317                            bstats.finishAddingCpuLocked(perc, totalUTime,
2318                                    totalSTime, cpuSpeedTimes);
2319                        }
2320                    }
2321                }
2322
2323                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2324                    mLastWriteTime = now;
2325                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2326                }
2327            }
2328        }
2329    }
2330
2331    @Override
2332    public void batteryNeedsCpuUpdate() {
2333        updateCpuStatsNow();
2334    }
2335
2336    @Override
2337    public void batteryPowerChanged(boolean onBattery) {
2338        // When plugging in, update the CPU stats first before changing
2339        // the plug state.
2340        updateCpuStatsNow();
2341        synchronized (this) {
2342            synchronized(mPidsSelfLocked) {
2343                mOnBattery = DEBUG_POWER ? true : onBattery;
2344            }
2345        }
2346    }
2347
2348    /**
2349     * Initialize the application bind args. These are passed to each
2350     * process when the bindApplication() IPC is sent to the process. They're
2351     * lazily setup to make sure the services are running when they're asked for.
2352     */
2353    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2354        if (mAppBindArgs == null) {
2355            mAppBindArgs = new HashMap<>();
2356
2357            // Isolated processes won't get this optimization, so that we don't
2358            // violate the rules about which services they have access to.
2359            if (!isolated) {
2360                // Setup the application init args
2361                mAppBindArgs.put("package", ServiceManager.getService("package"));
2362                mAppBindArgs.put("window", ServiceManager.getService("window"));
2363                mAppBindArgs.put(Context.ALARM_SERVICE,
2364                        ServiceManager.getService(Context.ALARM_SERVICE));
2365            }
2366        }
2367        return mAppBindArgs;
2368    }
2369
2370    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2371        if (mFocusedActivity != r) {
2372            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2373            mFocusedActivity = r;
2374            if (r.task != null && r.task.voiceInteractor != null) {
2375                startRunningVoiceLocked();
2376            } else {
2377                finishRunningVoiceLocked();
2378            }
2379            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2380            if (r != null) {
2381                mWindowManager.setFocusedApp(r.appToken, true);
2382            }
2383            applyUpdateLockStateLocked(r);
2384        }
2385        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2386                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2387    }
2388
2389    final void clearFocusedActivity(ActivityRecord r) {
2390        if (mFocusedActivity == r) {
2391            mFocusedActivity = null;
2392        }
2393    }
2394
2395    @Override
2396    public void setFocusedStack(int stackId) {
2397        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2398        synchronized (ActivityManagerService.this) {
2399            ActivityStack stack = mStackSupervisor.getStack(stackId);
2400            if (stack != null) {
2401                ActivityRecord r = stack.topRunningActivityLocked(null);
2402                if (r != null) {
2403                    setFocusedActivityLocked(r, "setFocusedStack");
2404                }
2405            }
2406        }
2407    }
2408
2409    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2410    @Override
2411    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2412        synchronized (ActivityManagerService.this) {
2413            if (listener != null) {
2414                mTaskStackListeners.register(listener);
2415            }
2416        }
2417    }
2418
2419    @Override
2420    public void notifyActivityDrawn(IBinder token) {
2421        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2422        synchronized (this) {
2423            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2424            if (r != null) {
2425                r.task.stack.notifyActivityDrawnLocked(r);
2426            }
2427        }
2428    }
2429
2430    final void applyUpdateLockStateLocked(ActivityRecord r) {
2431        // Modifications to the UpdateLock state are done on our handler, outside
2432        // the activity manager's locks.  The new state is determined based on the
2433        // state *now* of the relevant activity record.  The object is passed to
2434        // the handler solely for logging detail, not to be consulted/modified.
2435        final boolean nextState = r != null && r.immersive;
2436        mHandler.sendMessage(
2437                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2438    }
2439
2440    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2441        Message msg = Message.obtain();
2442        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2443        msg.obj = r.task.askedCompatMode ? null : r;
2444        mHandler.sendMessage(msg);
2445    }
2446
2447    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2448            String what, Object obj, ProcessRecord srcApp) {
2449        app.lastActivityTime = now;
2450
2451        if (app.activities.size() > 0) {
2452            // Don't want to touch dependent processes that are hosting activities.
2453            return index;
2454        }
2455
2456        int lrui = mLruProcesses.lastIndexOf(app);
2457        if (lrui < 0) {
2458            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2459                    + what + " " + obj + " from " + srcApp);
2460            return index;
2461        }
2462
2463        if (lrui >= index) {
2464            // Don't want to cause this to move dependent processes *back* in the
2465            // list as if they were less frequently used.
2466            return index;
2467        }
2468
2469        if (lrui >= mLruProcessActivityStart) {
2470            // Don't want to touch dependent processes that are hosting activities.
2471            return index;
2472        }
2473
2474        mLruProcesses.remove(lrui);
2475        if (index > 0) {
2476            index--;
2477        }
2478        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2479                + " in LRU list: " + app);
2480        mLruProcesses.add(index, app);
2481        return index;
2482    }
2483
2484    final void removeLruProcessLocked(ProcessRecord app) {
2485        int lrui = mLruProcesses.lastIndexOf(app);
2486        if (lrui >= 0) {
2487            if (!app.killed) {
2488                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2489                Process.killProcessQuiet(app.pid);
2490                Process.killProcessGroup(app.info.uid, app.pid);
2491            }
2492            if (lrui <= mLruProcessActivityStart) {
2493                mLruProcessActivityStart--;
2494            }
2495            if (lrui <= mLruProcessServiceStart) {
2496                mLruProcessServiceStart--;
2497            }
2498            mLruProcesses.remove(lrui);
2499        }
2500    }
2501
2502    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2503            ProcessRecord client) {
2504        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2505                || app.treatLikeActivity;
2506        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2507        if (!activityChange && hasActivity) {
2508            // The process has activities, so we are only allowing activity-based adjustments
2509            // to move it.  It should be kept in the front of the list with other
2510            // processes that have activities, and we don't want those to change their
2511            // order except due to activity operations.
2512            return;
2513        }
2514
2515        mLruSeq++;
2516        final long now = SystemClock.uptimeMillis();
2517        app.lastActivityTime = now;
2518
2519        // First a quick reject: if the app is already at the position we will
2520        // put it, then there is nothing to do.
2521        if (hasActivity) {
2522            final int N = mLruProcesses.size();
2523            if (N > 0 && mLruProcesses.get(N-1) == app) {
2524                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2525                return;
2526            }
2527        } else {
2528            if (mLruProcessServiceStart > 0
2529                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2530                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2531                return;
2532            }
2533        }
2534
2535        int lrui = mLruProcesses.lastIndexOf(app);
2536
2537        if (app.persistent && lrui >= 0) {
2538            // We don't care about the position of persistent processes, as long as
2539            // they are in the list.
2540            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2541            return;
2542        }
2543
2544        /* In progress: compute new position first, so we can avoid doing work
2545           if the process is not actually going to move.  Not yet working.
2546        int addIndex;
2547        int nextIndex;
2548        boolean inActivity = false, inService = false;
2549        if (hasActivity) {
2550            // Process has activities, put it at the very tipsy-top.
2551            addIndex = mLruProcesses.size();
2552            nextIndex = mLruProcessServiceStart;
2553            inActivity = true;
2554        } else if (hasService) {
2555            // Process has services, put it at the top of the service list.
2556            addIndex = mLruProcessActivityStart;
2557            nextIndex = mLruProcessServiceStart;
2558            inActivity = true;
2559            inService = true;
2560        } else  {
2561            // Process not otherwise of interest, it goes to the top of the non-service area.
2562            addIndex = mLruProcessServiceStart;
2563            if (client != null) {
2564                int clientIndex = mLruProcesses.lastIndexOf(client);
2565                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2566                        + app);
2567                if (clientIndex >= 0 && addIndex > clientIndex) {
2568                    addIndex = clientIndex;
2569                }
2570            }
2571            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2572        }
2573
2574        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2575                + mLruProcessActivityStart + "): " + app);
2576        */
2577
2578        if (lrui >= 0) {
2579            if (lrui < mLruProcessActivityStart) {
2580                mLruProcessActivityStart--;
2581            }
2582            if (lrui < mLruProcessServiceStart) {
2583                mLruProcessServiceStart--;
2584            }
2585            /*
2586            if (addIndex > lrui) {
2587                addIndex--;
2588            }
2589            if (nextIndex > lrui) {
2590                nextIndex--;
2591            }
2592            */
2593            mLruProcesses.remove(lrui);
2594        }
2595
2596        /*
2597        mLruProcesses.add(addIndex, app);
2598        if (inActivity) {
2599            mLruProcessActivityStart++;
2600        }
2601        if (inService) {
2602            mLruProcessActivityStart++;
2603        }
2604        */
2605
2606        int nextIndex;
2607        if (hasActivity) {
2608            final int N = mLruProcesses.size();
2609            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2610                // Process doesn't have activities, but has clients with
2611                // activities...  move it up, but one below the top (the top
2612                // should always have a real activity).
2613                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2614                mLruProcesses.add(N-1, app);
2615                // To keep it from spamming the LRU list (by making a bunch of clients),
2616                // we will push down any other entries owned by the app.
2617                final int uid = app.info.uid;
2618                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2619                    ProcessRecord subProc = mLruProcesses.get(i);
2620                    if (subProc.info.uid == uid) {
2621                        // We want to push this one down the list.  If the process after
2622                        // it is for the same uid, however, don't do so, because we don't
2623                        // want them internally to be re-ordered.
2624                        if (mLruProcesses.get(i-1).info.uid != uid) {
2625                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2626                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2627                            ProcessRecord tmp = mLruProcesses.get(i);
2628                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2629                            mLruProcesses.set(i-1, tmp);
2630                            i--;
2631                        }
2632                    } else {
2633                        // A gap, we can stop here.
2634                        break;
2635                    }
2636                }
2637            } else {
2638                // Process has activities, put it at the very tipsy-top.
2639                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2640                mLruProcesses.add(app);
2641            }
2642            nextIndex = mLruProcessServiceStart;
2643        } else if (hasService) {
2644            // Process has services, put it at the top of the service list.
2645            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2646            mLruProcesses.add(mLruProcessActivityStart, app);
2647            nextIndex = mLruProcessServiceStart;
2648            mLruProcessActivityStart++;
2649        } else  {
2650            // Process not otherwise of interest, it goes to the top of the non-service area.
2651            int index = mLruProcessServiceStart;
2652            if (client != null) {
2653                // If there is a client, don't allow the process to be moved up higher
2654                // in the list than that client.
2655                int clientIndex = mLruProcesses.lastIndexOf(client);
2656                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2657                        + " when updating " + app);
2658                if (clientIndex <= lrui) {
2659                    // Don't allow the client index restriction to push it down farther in the
2660                    // list than it already is.
2661                    clientIndex = lrui;
2662                }
2663                if (clientIndex >= 0 && index > clientIndex) {
2664                    index = clientIndex;
2665                }
2666            }
2667            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2668            mLruProcesses.add(index, app);
2669            nextIndex = index-1;
2670            mLruProcessActivityStart++;
2671            mLruProcessServiceStart++;
2672        }
2673
2674        // If the app is currently using a content provider or service,
2675        // bump those processes as well.
2676        for (int j=app.connections.size()-1; j>=0; j--) {
2677            ConnectionRecord cr = app.connections.valueAt(j);
2678            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2679                    && cr.binding.service.app != null
2680                    && cr.binding.service.app.lruSeq != mLruSeq
2681                    && !cr.binding.service.app.persistent) {
2682                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2683                        "service connection", cr, app);
2684            }
2685        }
2686        for (int j=app.conProviders.size()-1; j>=0; j--) {
2687            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2688            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2689                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2690                        "provider reference", cpr, app);
2691            }
2692        }
2693    }
2694
2695    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2696        if (uid == Process.SYSTEM_UID) {
2697            // The system gets to run in any process.  If there are multiple
2698            // processes with the same uid, just pick the first (this
2699            // should never happen).
2700            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2701            if (procs == null) return null;
2702            final int N = procs.size();
2703            for (int i = 0; i < N; i++) {
2704                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2705            }
2706        }
2707        ProcessRecord proc = mProcessNames.get(processName, uid);
2708        if (false && proc != null && !keepIfLarge
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2710                && proc.lastCachedPss >= 4000) {
2711            // Turn this condition on to cause killing to happen regularly, for testing.
2712            if (proc.baseProcessTracker != null) {
2713                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714            }
2715            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2716        } else if (proc != null && !keepIfLarge
2717                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2718                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2719            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2720            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2721                if (proc.baseProcessTracker != null) {
2722                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2723                }
2724                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2725            }
2726        }
2727        return proc;
2728    }
2729
2730    void ensurePackageDexOpt(String packageName) {
2731        IPackageManager pm = AppGlobals.getPackageManager();
2732        try {
2733            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2734                mDidDexOpt = true;
2735            }
2736        } catch (RemoteException e) {
2737        }
2738    }
2739
2740    boolean isNextTransitionForward() {
2741        int transit = mWindowManager.getPendingAppTransition();
2742        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2743                || transit == AppTransition.TRANSIT_TASK_OPEN
2744                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2745    }
2746
2747    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2748            String processName, String abiOverride, int uid, Runnable crashHandler) {
2749        synchronized(this) {
2750            ApplicationInfo info = new ApplicationInfo();
2751            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2752            // For isolated processes, the former contains the parent's uid and the latter the
2753            // actual uid of the isolated process.
2754            // In the special case introduced by this method (which is, starting an isolated
2755            // process directly from the SystemServer without an actual parent app process) the
2756            // closest thing to a parent's uid is SYSTEM_UID.
2757            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2758            // the |isolated| logic in the ProcessRecord constructor.
2759            info.uid = Process.SYSTEM_UID;
2760            info.processName = processName;
2761            info.className = entryPoint;
2762            info.packageName = "android";
2763            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2764                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2765                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2766                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2767                    crashHandler);
2768            return proc != null ? proc.pid : 0;
2769        }
2770    }
2771
2772    final ProcessRecord startProcessLocked(String processName,
2773            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2774            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2775            boolean isolated, boolean keepIfLarge) {
2776        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2777                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2778                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2779                null /* crashHandler */);
2780    }
2781
2782    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2783            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2784            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2785            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2786        long startTime = SystemClock.elapsedRealtime();
2787        ProcessRecord app;
2788        if (!isolated) {
2789            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2790            checkTime(startTime, "startProcess: after getProcessRecord");
2791        } else {
2792            // If this is an isolated process, it can't re-use an existing process.
2793            app = null;
2794        }
2795        // We don't have to do anything more if:
2796        // (1) There is an existing application record; and
2797        // (2) The caller doesn't think it is dead, OR there is no thread
2798        //     object attached to it so we know it couldn't have crashed; and
2799        // (3) There is a pid assigned to it, so it is either starting or
2800        //     already running.
2801        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2802                + " app=" + app + " knownToBeDead=" + knownToBeDead
2803                + " thread=" + (app != null ? app.thread : null)
2804                + " pid=" + (app != null ? app.pid : -1));
2805        if (app != null && app.pid > 0) {
2806            if (!knownToBeDead || app.thread == null) {
2807                // We already have the app running, or are waiting for it to
2808                // come up (we have a pid but not yet its thread), so keep it.
2809                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2810                // If this is a new package in the process, add the package to the list
2811                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2812                checkTime(startTime, "startProcess: done, added package to proc");
2813                return app;
2814            }
2815
2816            // An application record is attached to a previous process,
2817            // clean it up now.
2818            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2819            checkTime(startTime, "startProcess: bad proc running, killing");
2820            Process.killProcessGroup(app.info.uid, app.pid);
2821            handleAppDiedLocked(app, true, true);
2822            checkTime(startTime, "startProcess: done killing old proc");
2823        }
2824
2825        String hostingNameStr = hostingName != null
2826                ? hostingName.flattenToShortString() : null;
2827
2828        if (!isolated) {
2829            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2830                // If we are in the background, then check to see if this process
2831                // is bad.  If so, we will just silently fail.
2832                if (mBadProcesses.get(info.processName, info.uid) != null) {
2833                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2834                            + "/" + info.processName);
2835                    return null;
2836                }
2837            } else {
2838                // When the user is explicitly starting a process, then clear its
2839                // crash count so that we won't make it bad until they see at
2840                // least one crash dialog again, and make the process good again
2841                // if it had been bad.
2842                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2843                        + "/" + info.processName);
2844                mProcessCrashTimes.remove(info.processName, info.uid);
2845                if (mBadProcesses.get(info.processName, info.uid) != null) {
2846                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2847                            UserHandle.getUserId(info.uid), info.uid,
2848                            info.processName);
2849                    mBadProcesses.remove(info.processName, info.uid);
2850                    if (app != null) {
2851                        app.bad = false;
2852                    }
2853                }
2854            }
2855        }
2856
2857        if (app == null) {
2858            checkTime(startTime, "startProcess: creating new process record");
2859            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2860            if (app == null) {
2861                Slog.w(TAG, "Failed making new process record for "
2862                        + processName + "/" + info.uid + " isolated=" + isolated);
2863                return null;
2864            }
2865            app.crashHandler = crashHandler;
2866            mProcessNames.put(processName, app.uid, app);
2867            if (isolated) {
2868                mIsolatedProcesses.put(app.uid, app);
2869            }
2870            checkTime(startTime, "startProcess: done creating new process record");
2871        } else {
2872            // If this is a new package in the process, add the package to the list
2873            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2874            checkTime(startTime, "startProcess: added package to existing proc");
2875        }
2876
2877        // If the system is not ready yet, then hold off on starting this
2878        // process until it is.
2879        if (!mProcessesReady
2880                && !isAllowedWhileBooting(info)
2881                && !allowWhileBooting) {
2882            if (!mProcessesOnHold.contains(app)) {
2883                mProcessesOnHold.add(app);
2884            }
2885            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2886            checkTime(startTime, "startProcess: returning with proc on hold");
2887            return app;
2888        }
2889
2890        checkTime(startTime, "startProcess: stepping in to startProcess");
2891        startProcessLocked(
2892                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2893        checkTime(startTime, "startProcess: done starting proc!");
2894        return (app.pid != 0) ? app : null;
2895    }
2896
2897    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2898        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2899    }
2900
2901    private final void startProcessLocked(ProcessRecord app,
2902            String hostingType, String hostingNameStr) {
2903        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2904                null /* entryPoint */, null /* entryPointArgs */);
2905    }
2906
2907    private final void startProcessLocked(ProcessRecord app, String hostingType,
2908            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2909        long startTime = SystemClock.elapsedRealtime();
2910        if (app.pid > 0 && app.pid != MY_PID) {
2911            checkTime(startTime, "startProcess: removing from pids map");
2912            synchronized (mPidsSelfLocked) {
2913                mPidsSelfLocked.remove(app.pid);
2914                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2915            }
2916            checkTime(startTime, "startProcess: done removing from pids map");
2917            app.setPid(0);
2918        }
2919
2920        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2921                "startProcessLocked removing on hold: " + app);
2922        mProcessesOnHold.remove(app);
2923
2924        checkTime(startTime, "startProcess: starting to update cpu stats");
2925        updateCpuStats();
2926        checkTime(startTime, "startProcess: done updating cpu stats");
2927
2928        try {
2929            int uid = app.uid;
2930
2931            int[] gids = null;
2932            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2933            if (!app.isolated) {
2934                int[] permGids = null;
2935                try {
2936                    checkTime(startTime, "startProcess: getting gids from package manager");
2937                    final PackageManager pm = mContext.getPackageManager();
2938                    permGids = pm.getPackageGids(app.info.packageName);
2939
2940                    if (Environment.isExternalStorageEmulated()) {
2941                        checkTime(startTime, "startProcess: checking external storage perm");
2942                        if (pm.checkPermission(
2943                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2944                                app.info.packageName) == PERMISSION_GRANTED) {
2945                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2946                        } else {
2947                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2948                        }
2949                    }
2950                } catch (PackageManager.NameNotFoundException e) {
2951                    Slog.w(TAG, "Unable to retrieve gids", e);
2952                }
2953
2954                /*
2955                 * Add shared application and profile GIDs so applications can share some
2956                 * resources like shared libraries and access user-wide resources
2957                 */
2958                if (permGids == null) {
2959                    gids = new int[2];
2960                } else {
2961                    gids = new int[permGids.length + 2];
2962                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2963                }
2964                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2965                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2966            }
2967            checkTime(startTime, "startProcess: building args");
2968            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2969                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2970                        && mTopComponent != null
2971                        && app.processName.equals(mTopComponent.getPackageName())) {
2972                    uid = 0;
2973                }
2974                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2975                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2976                    uid = 0;
2977                }
2978            }
2979            int debugFlags = 0;
2980            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2982                // Also turn on CheckJNI for debuggable apps. It's quite
2983                // awkward to turn on otherwise.
2984                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2985            }
2986            // Run the app in safe mode if its manifest requests so or the
2987            // system is booted in safe mode.
2988            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2989                mSafeMode == true) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2991            }
2992            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2994            }
2995            String jitDebugProperty = SystemProperties.get("debug.usejit");
2996            if ("true".equals(jitDebugProperty)) {
2997                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
2998            } else if (!"false".equals(jitDebugProperty)) {
2999                // If we didn't force disable by setting false, defer to the dalvik vm options.
3000                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3001                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3002                }
3003            }
3004            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3006            }
3007            if ("1".equals(SystemProperties.get("debug.assert"))) {
3008                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3009            }
3010
3011            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3012            if (requiredAbi == null) {
3013                requiredAbi = Build.SUPPORTED_ABIS[0];
3014            }
3015
3016            String instructionSet = null;
3017            if (app.info.primaryCpuAbi != null) {
3018                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3019            }
3020
3021            app.gids = gids;
3022            app.requiredAbi = requiredAbi;
3023            app.instructionSet = instructionSet;
3024
3025            // Start the process.  It will either succeed and return a result containing
3026            // the PID of the new process, or else throw a RuntimeException.
3027            boolean isActivityProcess = (entryPoint == null);
3028            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3029            checkTime(startTime, "startProcess: asking zygote to start proc");
3030            Process.ProcessStartResult startResult = Process.start(entryPoint,
3031                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3032                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3033                    app.info.dataDir, entryPointArgs);
3034            checkTime(startTime, "startProcess: returned from zygote!");
3035
3036            if (app.isolated) {
3037                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3038            }
3039            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3040            checkTime(startTime, "startProcess: done updating battery stats");
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            checkTime(startTime, "startProcess: building log message");
3052            StringBuilder buf = mStringBuilder;
3053            buf.setLength(0);
3054            buf.append("Start proc ");
3055            buf.append(startResult.pid);
3056            buf.append(':');
3057            buf.append(app.processName);
3058            buf.append('/');
3059            UserHandle.formatUid(buf, uid);
3060            if (!isActivityProcess) {
3061                buf.append(" [");
3062                buf.append(entryPoint);
3063                buf.append("]");
3064            }
3065            buf.append(" for ");
3066            buf.append(hostingType);
3067            if (hostingNameStr != null) {
3068                buf.append(" ");
3069                buf.append(hostingNameStr);
3070            }
3071            Slog.i(TAG, buf.toString());
3072            app.setPid(startResult.pid);
3073            app.usingWrapper = startResult.usingWrapper;
3074            app.removed = false;
3075            app.killed = false;
3076            app.killedByAm = false;
3077            checkTime(startTime, "startProcess: starting to update pids map");
3078            synchronized (mPidsSelfLocked) {
3079                this.mPidsSelfLocked.put(startResult.pid, app);
3080                if (isActivityProcess) {
3081                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3082                    msg.obj = app;
3083                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3084                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3085                }
3086            }
3087            checkTime(startTime, "startProcess: done updating pids map");
3088        } catch (RuntimeException e) {
3089            // XXX do better error recovery.
3090            app.setPid(0);
3091            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3092            if (app.isolated) {
3093                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3094            }
3095            Slog.e(TAG, "Failure starting process " + app.processName, e);
3096        }
3097    }
3098
3099    void updateUsageStats(ActivityRecord component, boolean resumed) {
3100        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3101        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3102        if (resumed) {
3103            if (mUsageStatsService != null) {
3104                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3105                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3106            }
3107            synchronized (stats) {
3108                stats.noteActivityResumedLocked(component.app.uid);
3109            }
3110        } else {
3111            if (mUsageStatsService != null) {
3112                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3113                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3114            }
3115            synchronized (stats) {
3116                stats.noteActivityPausedLocked(component.app.uid);
3117            }
3118        }
3119    }
3120
3121    Intent getHomeIntent() {
3122        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3123        intent.setComponent(mTopComponent);
3124        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3125            intent.addCategory(Intent.CATEGORY_HOME);
3126        }
3127        return intent;
3128    }
3129
3130    boolean startHomeActivityLocked(int userId, String reason) {
3131        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3132                && mTopAction == null) {
3133            // We are running in factory test mode, but unable to find
3134            // the factory test app, so just sit around displaying the
3135            // error message and don't try to start anything.
3136            return false;
3137        }
3138        Intent intent = getHomeIntent();
3139        ActivityInfo aInfo =
3140            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3141        if (aInfo != null) {
3142            intent.setComponent(new ComponentName(
3143                    aInfo.applicationInfo.packageName, aInfo.name));
3144            // Don't do this if the home app is currently being
3145            // instrumented.
3146            aInfo = new ActivityInfo(aInfo);
3147            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3148            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3149                    aInfo.applicationInfo.uid, true);
3150            if (app == null || app.instrumentationClass == null) {
3151                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3152                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3153            }
3154        }
3155
3156        return true;
3157    }
3158
3159    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3160        ActivityInfo ai = null;
3161        ComponentName comp = intent.getComponent();
3162        try {
3163            if (comp != null) {
3164                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3165            } else {
3166                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3167                        intent,
3168                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3169                            flags, userId);
3170
3171                if (info != null) {
3172                    ai = info.activityInfo;
3173                }
3174            }
3175        } catch (RemoteException e) {
3176            // ignore
3177        }
3178
3179        return ai;
3180    }
3181
3182    /**
3183     * Starts the "new version setup screen" if appropriate.
3184     */
3185    void startSetupActivityLocked() {
3186        // Only do this once per boot.
3187        if (mCheckedForSetup) {
3188            return;
3189        }
3190
3191        // We will show this screen if the current one is a different
3192        // version than the last one shown, and we are not running in
3193        // low-level factory test mode.
3194        final ContentResolver resolver = mContext.getContentResolver();
3195        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3196                Settings.Global.getInt(resolver,
3197                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3198            mCheckedForSetup = true;
3199
3200            // See if we should be showing the platform update setup UI.
3201            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3202            List<ResolveInfo> ris = mContext.getPackageManager()
3203                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3204
3205            // We don't allow third party apps to replace this.
3206            ResolveInfo ri = null;
3207            for (int i=0; ris != null && i<ris.size(); i++) {
3208                if ((ris.get(i).activityInfo.applicationInfo.flags
3209                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3210                    ri = ris.get(i);
3211                    break;
3212                }
3213            }
3214
3215            if (ri != null) {
3216                String vers = ri.activityInfo.metaData != null
3217                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3218                        : null;
3219                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3220                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3221                            Intent.METADATA_SETUP_VERSION);
3222                }
3223                String lastVers = Settings.Secure.getString(
3224                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3225                if (vers != null && !vers.equals(lastVers)) {
3226                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3227                    intent.setComponent(new ComponentName(
3228                            ri.activityInfo.packageName, ri.activityInfo.name));
3229                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3230                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3231                            null);
3232                }
3233            }
3234        }
3235    }
3236
3237    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3238        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3239    }
3240
3241    void enforceNotIsolatedCaller(String caller) {
3242        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3243            throw new SecurityException("Isolated process not allowed to call " + caller);
3244        }
3245    }
3246
3247    void enforceShellRestriction(String restriction, int userHandle) {
3248        if (Binder.getCallingUid() == Process.SHELL_UID) {
3249            if (userHandle < 0
3250                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3251                throw new SecurityException("Shell does not have permission to access user "
3252                        + userHandle);
3253            }
3254        }
3255    }
3256
3257    @Override
3258    public int getFrontActivityScreenCompatMode() {
3259        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3260        synchronized (this) {
3261            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3262        }
3263    }
3264
3265    @Override
3266    public void setFrontActivityScreenCompatMode(int mode) {
3267        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3268                "setFrontActivityScreenCompatMode");
3269        synchronized (this) {
3270            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3271        }
3272    }
3273
3274    @Override
3275    public int getPackageScreenCompatMode(String packageName) {
3276        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3277        synchronized (this) {
3278            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3279        }
3280    }
3281
3282    @Override
3283    public void setPackageScreenCompatMode(String packageName, int mode) {
3284        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3285                "setPackageScreenCompatMode");
3286        synchronized (this) {
3287            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3288        }
3289    }
3290
3291    @Override
3292    public boolean getPackageAskScreenCompat(String packageName) {
3293        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3294        synchronized (this) {
3295            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3296        }
3297    }
3298
3299    @Override
3300    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3301        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3302                "setPackageAskScreenCompat");
3303        synchronized (this) {
3304            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3305        }
3306    }
3307
3308    private void dispatchProcessesChanged() {
3309        int N;
3310        synchronized (this) {
3311            N = mPendingProcessChanges.size();
3312            if (mActiveProcessChanges.length < N) {
3313                mActiveProcessChanges = new ProcessChangeItem[N];
3314            }
3315            mPendingProcessChanges.toArray(mActiveProcessChanges);
3316            mAvailProcessChanges.addAll(mPendingProcessChanges);
3317            mPendingProcessChanges.clear();
3318            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3319        }
3320
3321        int i = mProcessObservers.beginBroadcast();
3322        while (i > 0) {
3323            i--;
3324            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3325            if (observer != null) {
3326                try {
3327                    for (int j=0; j<N; j++) {
3328                        ProcessChangeItem item = mActiveProcessChanges[j];
3329                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": "
3332                                    + item.foregroundActivities);
3333                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3334                                    item.foregroundActivities);
3335                        }
3336                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3337                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3338                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3339                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3340                        }
3341                    }
3342                } catch (RemoteException e) {
3343                }
3344            }
3345        }
3346        mProcessObservers.finishBroadcast();
3347    }
3348
3349    private void dispatchProcessDied(int pid, int uid) {
3350        int i = mProcessObservers.beginBroadcast();
3351        while (i > 0) {
3352            i--;
3353            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3354            if (observer != null) {
3355                try {
3356                    observer.onProcessDied(pid, uid);
3357                } catch (RemoteException e) {
3358                }
3359            }
3360        }
3361        mProcessObservers.finishBroadcast();
3362    }
3363
3364    @Override
3365    public final int startActivity(IApplicationThread caller, String callingPackage,
3366            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3367            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3368        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3369            resultWho, requestCode, startFlags, profilerInfo, options,
3370            UserHandle.getCallingUserId());
3371    }
3372
3373    @Override
3374    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3375            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3376            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3377        enforceNotIsolatedCaller("startActivity");
3378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3379                false, ALLOW_FULL_ONLY, "startActivity", null);
3380        // TODO: Switch to user app stacks here.
3381        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3382                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3383                profilerInfo, null, null, options, userId, null, null);
3384    }
3385
3386    @Override
3387    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3388            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3389            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3390
3391        // This is very dangerous -- it allows you to perform a start activity (including
3392        // permission grants) as any app that may launch one of your own activities.  So
3393        // we will only allow this to be done from activities that are part of the core framework,
3394        // and then only when they are running as the system.
3395        final ActivityRecord sourceRecord;
3396        final int targetUid;
3397        final String targetPackage;
3398        synchronized (this) {
3399            if (resultTo == null) {
3400                throw new SecurityException("Must be called from an activity");
3401            }
3402            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3403            if (sourceRecord == null) {
3404                throw new SecurityException("Called with bad activity token: " + resultTo);
3405            }
3406            if (!sourceRecord.info.packageName.equals("android")) {
3407                throw new SecurityException(
3408                        "Must be called from an activity that is declared in the android package");
3409            }
3410            if (sourceRecord.app == null) {
3411                throw new SecurityException("Called without a process attached to activity");
3412            }
3413            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3414                // This is still okay, as long as this activity is running under the
3415                // uid of the original calling activity.
3416                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3417                    throw new SecurityException(
3418                            "Calling activity in uid " + sourceRecord.app.uid
3419                                    + " must be system uid or original calling uid "
3420                                    + sourceRecord.launchedFromUid);
3421                }
3422            }
3423            targetUid = sourceRecord.launchedFromUid;
3424            targetPackage = sourceRecord.launchedFromPackage;
3425        }
3426
3427        if (userId == UserHandle.USER_NULL) {
3428            userId = UserHandle.getUserId(sourceRecord.app.uid);
3429        }
3430
3431        // TODO: Switch to user app stacks here.
3432        try {
3433            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3434                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3435                    null, null, options, userId, null, null);
3436            return ret;
3437        } catch (SecurityException e) {
3438            // XXX need to figure out how to propagate to original app.
3439            // A SecurityException here is generally actually a fault of the original
3440            // calling activity (such as a fairly granting permissions), so propagate it
3441            // back to them.
3442            /*
3443            StringBuilder msg = new StringBuilder();
3444            msg.append("While launching");
3445            msg.append(intent.toString());
3446            msg.append(": ");
3447            msg.append(e.getMessage());
3448            */
3449            throw e;
3450        }
3451    }
3452
3453    @Override
3454    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3456            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityAndWait");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3460        WaitResult res = new WaitResult();
3461        // TODO: Switch to user app stacks here.
3462        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3463                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3464                options, userId, null, null);
3465        return res;
3466    }
3467
3468    @Override
3469    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3470            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3471            int startFlags, Configuration config, Bundle options, int userId) {
3472        enforceNotIsolatedCaller("startActivityWithConfig");
3473        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3474                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3475        // TODO: Switch to user app stacks here.
3476        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3477                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3478                null, null, config, options, userId, null, null);
3479        return ret;
3480    }
3481
3482    @Override
3483    public int startActivityIntentSender(IApplicationThread caller,
3484            IntentSender intent, Intent fillInIntent, String resolvedType,
3485            IBinder resultTo, String resultWho, int requestCode,
3486            int flagsMask, int flagsValues, Bundle options) {
3487        enforceNotIsolatedCaller("startActivityIntentSender");
3488        // Refuse possible leaked file descriptors
3489        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3490            throw new IllegalArgumentException("File descriptors passed in Intent");
3491        }
3492
3493        IIntentSender sender = intent.getTarget();
3494        if (!(sender instanceof PendingIntentRecord)) {
3495            throw new IllegalArgumentException("Bad PendingIntent object");
3496        }
3497
3498        PendingIntentRecord pir = (PendingIntentRecord)sender;
3499
3500        synchronized (this) {
3501            // If this is coming from the currently resumed activity, it is
3502            // effectively saying that app switches are allowed at this point.
3503            final ActivityStack stack = getFocusedStack();
3504            if (stack.mResumedActivity != null &&
3505                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3506                mAppSwitchesAllowedTime = 0;
3507            }
3508        }
3509        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3510                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3511        return ret;
3512    }
3513
3514    @Override
3515    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3516            Intent intent, String resolvedType, IVoiceInteractionSession session,
3517            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3518            Bundle options, int userId) {
3519        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3520                != PackageManager.PERMISSION_GRANTED) {
3521            String msg = "Permission Denial: startVoiceActivity() from pid="
3522                    + Binder.getCallingPid()
3523                    + ", uid=" + Binder.getCallingUid()
3524                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3525            Slog.w(TAG, msg);
3526            throw new SecurityException(msg);
3527        }
3528        if (session == null || interactor == null) {
3529            throw new NullPointerException("null session or interactor");
3530        }
3531        userId = handleIncomingUser(callingPid, callingUid, userId,
3532                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3533        // TODO: Switch to user app stacks here.
3534        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3535                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3536                null, options, userId, null, null);
3537    }
3538
3539    @Override
3540    public boolean startNextMatchingActivity(IBinder callingActivity,
3541            Intent intent, Bundle options) {
3542        // Refuse possible leaked file descriptors
3543        if (intent != null && intent.hasFileDescriptors() == true) {
3544            throw new IllegalArgumentException("File descriptors passed in Intent");
3545        }
3546
3547        synchronized (this) {
3548            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3549            if (r == null) {
3550                ActivityOptions.abort(options);
3551                return false;
3552            }
3553            if (r.app == null || r.app.thread == null) {
3554                // The caller is not running...  d'oh!
3555                ActivityOptions.abort(options);
3556                return false;
3557            }
3558            intent = new Intent(intent);
3559            // The caller is not allowed to change the data.
3560            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3561            // And we are resetting to find the next component...
3562            intent.setComponent(null);
3563
3564            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3565
3566            ActivityInfo aInfo = null;
3567            try {
3568                List<ResolveInfo> resolves =
3569                    AppGlobals.getPackageManager().queryIntentActivities(
3570                            intent, r.resolvedType,
3571                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3572                            UserHandle.getCallingUserId());
3573
3574                // Look for the original activity in the list...
3575                final int N = resolves != null ? resolves.size() : 0;
3576                for (int i=0; i<N; i++) {
3577                    ResolveInfo rInfo = resolves.get(i);
3578                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3579                            && rInfo.activityInfo.name.equals(r.info.name)) {
3580                        // We found the current one...  the next matching is
3581                        // after it.
3582                        i++;
3583                        if (i<N) {
3584                            aInfo = resolves.get(i).activityInfo;
3585                        }
3586                        if (debug) {
3587                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3588                                    + "/" + r.info.name);
3589                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3590                                    + "/" + aInfo.name);
3591                        }
3592                        break;
3593                    }
3594                }
3595            } catch (RemoteException e) {
3596            }
3597
3598            if (aInfo == null) {
3599                // Nobody who is next!
3600                ActivityOptions.abort(options);
3601                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3602                return false;
3603            }
3604
3605            intent.setComponent(new ComponentName(
3606                    aInfo.applicationInfo.packageName, aInfo.name));
3607            intent.setFlags(intent.getFlags()&~(
3608                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3609                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3610                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3611                    Intent.FLAG_ACTIVITY_NEW_TASK));
3612
3613            // Okay now we need to start the new activity, replacing the
3614            // currently running activity.  This is a little tricky because
3615            // we want to start the new one as if the current one is finished,
3616            // but not finish the current one first so that there is no flicker.
3617            // And thus...
3618            final boolean wasFinishing = r.finishing;
3619            r.finishing = true;
3620
3621            // Propagate reply information over to the new activity.
3622            final ActivityRecord resultTo = r.resultTo;
3623            final String resultWho = r.resultWho;
3624            final int requestCode = r.requestCode;
3625            r.resultTo = null;
3626            if (resultTo != null) {
3627                resultTo.removeResultsLocked(r, resultWho, requestCode);
3628            }
3629
3630            final long origId = Binder.clearCallingIdentity();
3631            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3632                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3633                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3634                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3635            Binder.restoreCallingIdentity(origId);
3636
3637            r.finishing = wasFinishing;
3638            if (res != ActivityManager.START_SUCCESS) {
3639                return false;
3640            }
3641            return true;
3642        }
3643    }
3644
3645    @Override
3646    public final int startActivityFromRecents(int taskId, Bundle options) {
3647        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3648            String msg = "Permission Denial: startActivityFromRecents called without " +
3649                    START_TASKS_FROM_RECENTS;
3650            Slog.w(TAG, msg);
3651            throw new SecurityException(msg);
3652        }
3653        return startActivityFromRecentsInner(taskId, options);
3654    }
3655
3656    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3657        final TaskRecord task;
3658        final int callingUid;
3659        final String callingPackage;
3660        final Intent intent;
3661        final int userId;
3662        synchronized (this) {
3663            task = recentTaskForIdLocked(taskId);
3664            if (task == null) {
3665                throw new IllegalArgumentException("Task " + taskId + " not found.");
3666            }
3667            if (task.getRootActivity() != null) {
3668                moveTaskToFrontLocked(task.taskId, 0, null);
3669                return ActivityManager.START_TASK_TO_FRONT;
3670            }
3671            callingUid = task.mCallingUid;
3672            callingPackage = task.mCallingPackage;
3673            intent = task.intent;
3674            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3675            userId = task.userId;
3676        }
3677        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3678                options, userId, null, task);
3679    }
3680
3681    final int startActivityInPackage(int uid, String callingPackage,
3682            Intent intent, String resolvedType, IBinder resultTo,
3683            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3684            IActivityContainer container, TaskRecord inTask) {
3685
3686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3687                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3688
3689        // TODO: Switch to user app stacks here.
3690        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3691                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3692                null, null, null, options, userId, container, inTask);
3693        return ret;
3694    }
3695
3696    @Override
3697    public final int startActivities(IApplicationThread caller, String callingPackage,
3698            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3699            int userId) {
3700        enforceNotIsolatedCaller("startActivities");
3701        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3702                false, ALLOW_FULL_ONLY, "startActivity", null);
3703        // TODO: Switch to user app stacks here.
3704        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3705                resolvedTypes, resultTo, options, userId);
3706        return ret;
3707    }
3708
3709    final int startActivitiesInPackage(int uid, String callingPackage,
3710            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3711            Bundle options, int userId) {
3712
3713        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3714                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3715        // TODO: Switch to user app stacks here.
3716        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3717                resultTo, options, userId);
3718        return ret;
3719    }
3720
3721    //explicitly remove thd old information in mRecentTasks when removing existing user.
3722    private void removeRecentTasksForUserLocked(int userId) {
3723        if(userId <= 0) {
3724            Slog.i(TAG, "Can't remove recent task on user " + userId);
3725            return;
3726        }
3727
3728        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3729            TaskRecord tr = mRecentTasks.get(i);
3730            if (tr.userId == userId) {
3731                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3732                        + " when finishing user" + userId);
3733                mRecentTasks.remove(i);
3734                tr.removedFromRecents();
3735            }
3736        }
3737
3738        // Remove tasks from persistent storage.
3739        notifyTaskPersisterLocked(null, true);
3740    }
3741
3742    // Sort by taskId
3743    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3744        @Override
3745        public int compare(TaskRecord lhs, TaskRecord rhs) {
3746            return rhs.taskId - lhs.taskId;
3747        }
3748    };
3749
3750    // Extract the affiliates of the chain containing mRecentTasks[start].
3751    private int processNextAffiliateChainLocked(int start) {
3752        final TaskRecord startTask = mRecentTasks.get(start);
3753        final int affiliateId = startTask.mAffiliatedTaskId;
3754
3755        // Quick identification of isolated tasks. I.e. those not launched behind.
3756        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3757                startTask.mNextAffiliate == null) {
3758            // There is still a slim chance that there are other tasks that point to this task
3759            // and that the chain is so messed up that this task no longer points to them but
3760            // the gain of this optimization outweighs the risk.
3761            startTask.inRecents = true;
3762            return start + 1;
3763        }
3764
3765        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3766        mTmpRecents.clear();
3767        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3768            final TaskRecord task = mRecentTasks.get(i);
3769            if (task.mAffiliatedTaskId == affiliateId) {
3770                mRecentTasks.remove(i);
3771                mTmpRecents.add(task);
3772            }
3773        }
3774
3775        // Sort them all by taskId. That is the order they were create in and that order will
3776        // always be correct.
3777        Collections.sort(mTmpRecents, mTaskRecordComparator);
3778
3779        // Go through and fix up the linked list.
3780        // The first one is the end of the chain and has no next.
3781        final TaskRecord first = mTmpRecents.get(0);
3782        first.inRecents = true;
3783        if (first.mNextAffiliate != null) {
3784            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3785            first.setNextAffiliate(null);
3786            notifyTaskPersisterLocked(first, false);
3787        }
3788        // Everything in the middle is doubly linked from next to prev.
3789        final int tmpSize = mTmpRecents.size();
3790        for (int i = 0; i < tmpSize - 1; ++i) {
3791            final TaskRecord next = mTmpRecents.get(i);
3792            final TaskRecord prev = mTmpRecents.get(i + 1);
3793            if (next.mPrevAffiliate != prev) {
3794                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3795                        " setting prev=" + prev);
3796                next.setPrevAffiliate(prev);
3797                notifyTaskPersisterLocked(next, false);
3798            }
3799            if (prev.mNextAffiliate != next) {
3800                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3801                        " setting next=" + next);
3802                prev.setNextAffiliate(next);
3803                notifyTaskPersisterLocked(prev, false);
3804            }
3805            prev.inRecents = true;
3806        }
3807        // The last one is the beginning of the list and has no prev.
3808        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3809        if (last.mPrevAffiliate != null) {
3810            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3811            last.setPrevAffiliate(null);
3812            notifyTaskPersisterLocked(last, false);
3813        }
3814
3815        // Insert the group back into mRecentTasks at start.
3816        mRecentTasks.addAll(start, mTmpRecents);
3817
3818        // Let the caller know where we left off.
3819        return start + tmpSize;
3820    }
3821
3822    /**
3823     * Update the recent tasks lists: make sure tasks should still be here (their
3824     * applications / activities still exist), update their availability, fixup ordering
3825     * of affiliations.
3826     */
3827    void cleanupRecentTasksLocked(int userId) {
3828        if (mRecentTasks == null) {
3829            // Happens when called from the packagemanager broadcast before boot.
3830            return;
3831        }
3832
3833        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3834        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3835        final IPackageManager pm = AppGlobals.getPackageManager();
3836        final ActivityInfo dummyAct = new ActivityInfo();
3837        final ApplicationInfo dummyApp = new ApplicationInfo();
3838
3839        int N = mRecentTasks.size();
3840
3841        int[] users = userId == UserHandle.USER_ALL
3842                ? getUsersLocked() : new int[] { userId };
3843        for (int user : users) {
3844            for (int i = 0; i < N; i++) {
3845                TaskRecord task = mRecentTasks.get(i);
3846                if (task.userId != user) {
3847                    // Only look at tasks for the user ID of interest.
3848                    continue;
3849                }
3850                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3851                    // This situation is broken, and we should just get rid of it now.
3852                    mRecentTasks.remove(i);
3853                    task.removedFromRecents();
3854                    i--;
3855                    N--;
3856                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3857                    continue;
3858                }
3859                // Check whether this activity is currently available.
3860                if (task.realActivity != null) {
3861                    ActivityInfo ai = availActCache.get(task.realActivity);
3862                    if (ai == null) {
3863                        try {
3864                            ai = pm.getActivityInfo(task.realActivity,
3865                                    PackageManager.GET_UNINSTALLED_PACKAGES
3866                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3867                        } catch (RemoteException e) {
3868                            // Will never happen.
3869                            continue;
3870                        }
3871                        if (ai == null) {
3872                            ai = dummyAct;
3873                        }
3874                        availActCache.put(task.realActivity, ai);
3875                    }
3876                    if (ai == dummyAct) {
3877                        // This could be either because the activity no longer exists, or the
3878                        // app is temporarily gone.  For the former we want to remove the recents
3879                        // entry; for the latter we want to mark it as unavailable.
3880                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3881                        if (app == null) {
3882                            try {
3883                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3884                                        PackageManager.GET_UNINSTALLED_PACKAGES
3885                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3886                            } catch (RemoteException e) {
3887                                // Will never happen.
3888                                continue;
3889                            }
3890                            if (app == null) {
3891                                app = dummyApp;
3892                            }
3893                            availAppCache.put(task.realActivity.getPackageName(), app);
3894                        }
3895                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3896                            // Doesn't exist any more!  Good-bye.
3897                            mRecentTasks.remove(i);
3898                            task.removedFromRecents();
3899                            i--;
3900                            N--;
3901                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3902                            continue;
3903                        } else {
3904                            // Otherwise just not available for now.
3905                            if (task.isAvailable) {
3906                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3907                                        + task);
3908                            }
3909                            task.isAvailable = false;
3910                        }
3911                    } else {
3912                        if (!ai.enabled || !ai.applicationInfo.enabled
3913                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3914                            if (task.isAvailable) {
3915                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3916                                        + task + " (enabled=" + ai.enabled + "/"
3917                                        + ai.applicationInfo.enabled +  " flags="
3918                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3919                            }
3920                            task.isAvailable = false;
3921                        } else {
3922                            if (!task.isAvailable) {
3923                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3924                                        + task);
3925                            }
3926                            task.isAvailable = true;
3927                        }
3928                    }
3929                }
3930            }
3931        }
3932
3933        // Verify the affiliate chain for each task.
3934        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3935        }
3936
3937        mTmpRecents.clear();
3938        // mRecentTasks is now in sorted, affiliated order.
3939    }
3940
3941    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3942        int N = mRecentTasks.size();
3943        TaskRecord top = task;
3944        int topIndex = taskIndex;
3945        while (top.mNextAffiliate != null && topIndex > 0) {
3946            top = top.mNextAffiliate;
3947            topIndex--;
3948        }
3949        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3950                + topIndex + " from intial " + taskIndex);
3951        // Find the end of the chain, doing a sanity check along the way.
3952        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3953        int endIndex = topIndex;
3954        TaskRecord prev = top;
3955        while (endIndex < N) {
3956            TaskRecord cur = mRecentTasks.get(endIndex);
3957            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3958                    + endIndex + " " + cur);
3959            if (cur == top) {
3960                // Verify start of the chain.
3961                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3962                    Slog.wtf(TAG, "Bad chain @" + endIndex
3963                            + ": first task has next affiliate: " + prev);
3964                    sane = false;
3965                    break;
3966                }
3967            } else {
3968                // Verify middle of the chain's next points back to the one before.
3969                if (cur.mNextAffiliate != prev
3970                        || cur.mNextAffiliateTaskId != prev.taskId) {
3971                    Slog.wtf(TAG, "Bad chain @" + endIndex
3972                            + ": middle task " + cur + " @" + endIndex
3973                            + " has bad next affiliate "
3974                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3975                            + ", expected " + prev);
3976                    sane = false;
3977                    break;
3978                }
3979            }
3980            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3981                // Chain ends here.
3982                if (cur.mPrevAffiliate != null) {
3983                    Slog.wtf(TAG, "Bad chain @" + endIndex
3984                            + ": last task " + cur + " has previous affiliate "
3985                            + cur.mPrevAffiliate);
3986                    sane = false;
3987                }
3988                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3989                break;
3990            } else {
3991                // Verify middle of the chain's prev points to a valid item.
3992                if (cur.mPrevAffiliate == null) {
3993                    Slog.wtf(TAG, "Bad chain @" + endIndex
3994                            + ": task " + cur + " has previous affiliate "
3995                            + cur.mPrevAffiliate + " but should be id "
3996                            + cur.mPrevAffiliate);
3997                    sane = false;
3998                    break;
3999                }
4000            }
4001            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4002                Slog.wtf(TAG, "Bad chain @" + endIndex
4003                        + ": task " + cur + " has affiliated id "
4004                        + cur.mAffiliatedTaskId + " but should be "
4005                        + task.mAffiliatedTaskId);
4006                sane = false;
4007                break;
4008            }
4009            prev = cur;
4010            endIndex++;
4011            if (endIndex >= N) {
4012                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4013                        + ": last task " + prev);
4014                sane = false;
4015                break;
4016            }
4017        }
4018        if (sane) {
4019            if (endIndex < taskIndex) {
4020                Slog.wtf(TAG, "Bad chain @" + endIndex
4021                        + ": did not extend to task " + task + " @" + taskIndex);
4022                sane = false;
4023            }
4024        }
4025        if (sane) {
4026            // All looks good, we can just move all of the affiliated tasks
4027            // to the top.
4028            for (int i=topIndex; i<=endIndex; i++) {
4029                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4030                        + " from " + i + " to " + (i-topIndex));
4031                TaskRecord cur = mRecentTasks.remove(i);
4032                mRecentTasks.add(i-topIndex, cur);
4033            }
4034            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4035                    + " to " + endIndex);
4036            return true;
4037        }
4038
4039        // Whoops, couldn't do it.
4040        return false;
4041    }
4042
4043    final void addRecentTaskLocked(TaskRecord task) {
4044        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4045                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4046                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4047
4048        int N = mRecentTasks.size();
4049        // Quick case: check if the top-most recent task is the same.
4050        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4051            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4052            return;
4053        }
4054        // Another quick case: check if this is part of a set of affiliated
4055        // tasks that are at the top.
4056        if (isAffiliated && N > 0 && task.inRecents
4057                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4058            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4059                    + " at top when adding " + task);
4060            return;
4061        }
4062        // Another quick case: never add voice sessions.
4063        if (task.voiceSession != null) {
4064            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4065            return;
4066        }
4067
4068        boolean needAffiliationFix = false;
4069
4070        // Slightly less quick case: the task is already in recents, so all we need
4071        // to do is move it.
4072        if (task.inRecents) {
4073            int taskIndex = mRecentTasks.indexOf(task);
4074            if (taskIndex >= 0) {
4075                if (!isAffiliated) {
4076                    // Simple case: this is not an affiliated task, so we just move it to the front.
4077                    mRecentTasks.remove(taskIndex);
4078                    mRecentTasks.add(0, task);
4079                    notifyTaskPersisterLocked(task, false);
4080                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4081                            + " from " + taskIndex);
4082                    return;
4083                } else {
4084                    // More complicated: need to keep all affiliated tasks together.
4085                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4086                        // All went well.
4087                        return;
4088                    }
4089
4090                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4091                    // everything and then go through our general path of adding a new task.
4092                    needAffiliationFix = true;
4093                }
4094            } else {
4095                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4096                needAffiliationFix = true;
4097            }
4098        }
4099
4100        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4101        trimRecentsForTaskLocked(task, true);
4102
4103        N = mRecentTasks.size();
4104        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4105            final TaskRecord tr = mRecentTasks.remove(N - 1);
4106            tr.removedFromRecents();
4107            N--;
4108        }
4109        task.inRecents = true;
4110        if (!isAffiliated || needAffiliationFix) {
4111            // If this is a simple non-affiliated task, or we had some failure trying to
4112            // handle it as part of an affilated task, then just place it at the top.
4113            mRecentTasks.add(0, task);
4114        } else if (isAffiliated) {
4115            // If this is a new affiliated task, then move all of the affiliated tasks
4116            // to the front and insert this new one.
4117            TaskRecord other = task.mNextAffiliate;
4118            if (other == null) {
4119                other = task.mPrevAffiliate;
4120            }
4121            if (other != null) {
4122                int otherIndex = mRecentTasks.indexOf(other);
4123                if (otherIndex >= 0) {
4124                    // Insert new task at appropriate location.
4125                    int taskIndex;
4126                    if (other == task.mNextAffiliate) {
4127                        // We found the index of our next affiliation, which is who is
4128                        // before us in the list, so add after that point.
4129                        taskIndex = otherIndex+1;
4130                    } else {
4131                        // We found the index of our previous affiliation, which is who is
4132                        // after us in the list, so add at their position.
4133                        taskIndex = otherIndex;
4134                    }
4135                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4136                            + taskIndex + ": " + task);
4137                    mRecentTasks.add(taskIndex, task);
4138
4139                    // Now move everything to the front.
4140                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4141                        // All went well.
4142                        return;
4143                    }
4144
4145                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4146                    // everything and then go through our general path of adding a new task.
4147                    needAffiliationFix = true;
4148                } else {
4149                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4150                            + other);
4151                    needAffiliationFix = true;
4152                }
4153            } else {
4154                if (DEBUG_RECENTS) Slog.d(TAG,
4155                        "addRecent: adding affiliated task without next/prev:" + task);
4156                needAffiliationFix = true;
4157            }
4158        }
4159        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4160
4161        if (needAffiliationFix) {
4162            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4163            cleanupRecentTasksLocked(task.userId);
4164        }
4165    }
4166
4167    /**
4168     * If needed, remove oldest existing entries in recents that are for the same kind
4169     * of task as the given one.
4170     */
4171    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4172        int N = mRecentTasks.size();
4173        final Intent intent = task.intent;
4174        final boolean document = intent != null && intent.isDocument();
4175
4176        int maxRecents = task.maxRecents - 1;
4177        for (int i=0; i<N; i++) {
4178            final TaskRecord tr = mRecentTasks.get(i);
4179            if (task != tr) {
4180                if (task.userId != tr.userId) {
4181                    continue;
4182                }
4183                if (i > MAX_RECENT_BITMAPS) {
4184                    tr.freeLastThumbnail();
4185                }
4186                final Intent trIntent = tr.intent;
4187                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4188                    (intent == null || !intent.filterEquals(trIntent))) {
4189                    continue;
4190                }
4191                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4192                if (document && trIsDocument) {
4193                    // These are the same document activity (not necessarily the same doc).
4194                    if (maxRecents > 0) {
4195                        --maxRecents;
4196                        continue;
4197                    }
4198                    // Hit the maximum number of documents for this task. Fall through
4199                    // and remove this document from recents.
4200                } else if (document || trIsDocument) {
4201                    // Only one of these is a document. Not the droid we're looking for.
4202                    continue;
4203                }
4204            }
4205
4206            if (!doTrim) {
4207                // If the caller is not actually asking for a trim, just tell them we reached
4208                // a point where the trim would happen.
4209                return i;
4210            }
4211
4212            // Either task and tr are the same or, their affinities match or their intents match
4213            // and neither of them is a document, or they are documents using the same activity
4214            // and their maxRecents has been reached.
4215            tr.disposeThumbnail();
4216            mRecentTasks.remove(i);
4217            if (task != tr) {
4218                tr.removedFromRecents();
4219            }
4220            i--;
4221            N--;
4222            if (task.intent == null) {
4223                // If the new recent task we are adding is not fully
4224                // specified, then replace it with the existing recent task.
4225                task = tr;
4226            }
4227            notifyTaskPersisterLocked(tr, false);
4228        }
4229
4230        return -1;
4231    }
4232
4233    @Override
4234    public void reportActivityFullyDrawn(IBinder token) {
4235        synchronized (this) {
4236            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4237            if (r == null) {
4238                return;
4239            }
4240            r.reportFullyDrawnLocked();
4241        }
4242    }
4243
4244    @Override
4245    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4246        synchronized (this) {
4247            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4248            if (r == null) {
4249                return;
4250            }
4251            final long origId = Binder.clearCallingIdentity();
4252            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4253            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4254                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4255            if (config != null) {
4256                r.frozenBeforeDestroy = true;
4257                if (!updateConfigurationLocked(config, r, false, false)) {
4258                    mStackSupervisor.resumeTopActivitiesLocked();
4259                }
4260            }
4261            Binder.restoreCallingIdentity(origId);
4262        }
4263    }
4264
4265    @Override
4266    public int getRequestedOrientation(IBinder token) {
4267        synchronized (this) {
4268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4269            if (r == null) {
4270                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4271            }
4272            return mWindowManager.getAppOrientation(r.appToken);
4273        }
4274    }
4275
4276    /**
4277     * This is the internal entry point for handling Activity.finish().
4278     *
4279     * @param token The Binder token referencing the Activity we want to finish.
4280     * @param resultCode Result code, if any, from this Activity.
4281     * @param resultData Result data (Intent), if any, from this Activity.
4282     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4283     *            the root Activity in the task.
4284     *
4285     * @return Returns true if the activity successfully finished, or false if it is still running.
4286     */
4287    @Override
4288    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4289            boolean finishTask) {
4290        // Refuse possible leaked file descriptors
4291        if (resultData != null && resultData.hasFileDescriptors() == true) {
4292            throw new IllegalArgumentException("File descriptors passed in Intent");
4293        }
4294
4295        synchronized(this) {
4296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4297            if (r == null) {
4298                return true;
4299            }
4300            // Keep track of the root activity of the task before we finish it
4301            TaskRecord tr = r.task;
4302            ActivityRecord rootR = tr.getRootActivity();
4303            if (rootR == null) {
4304                Slog.w(TAG, "Finishing task with all activities already finished");
4305            }
4306            // Do not allow task to finish in Lock Task mode.
4307            if (tr == mStackSupervisor.mLockTaskModeTask) {
4308                if (rootR == r) {
4309                    Slog.i(TAG, "Not finishing task in lock task mode");
4310                    mStackSupervisor.showLockTaskToast();
4311                    return false;
4312                }
4313            }
4314            if (mController != null) {
4315                // Find the first activity that is not finishing.
4316                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4317                if (next != null) {
4318                    // ask watcher if this is allowed
4319                    boolean resumeOK = true;
4320                    try {
4321                        resumeOK = mController.activityResuming(next.packageName);
4322                    } catch (RemoteException e) {
4323                        mController = null;
4324                        Watchdog.getInstance().setActivityController(null);
4325                    }
4326
4327                    if (!resumeOK) {
4328                        Slog.i(TAG, "Not finishing activity because controller resumed");
4329                        return false;
4330                    }
4331                }
4332            }
4333            final long origId = Binder.clearCallingIdentity();
4334            try {
4335                boolean res;
4336                if (finishTask && r == rootR) {
4337                    // If requested, remove the task that is associated to this activity only if it
4338                    // was the root activity in the task. The result code and data is ignored
4339                    // because we don't support returning them across task boundaries.
4340                    res = removeTaskByIdLocked(tr.taskId, false);
4341                    if (!res) {
4342                        Slog.i(TAG, "Removing task failed to finish activity");
4343                    }
4344                } else {
4345                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4346                            resultData, "app-request", true);
4347                    if (!res) {
4348                        Slog.i(TAG, "Failed to finish by app-request");
4349                    }
4350                }
4351                return res;
4352            } finally {
4353                Binder.restoreCallingIdentity(origId);
4354            }
4355        }
4356    }
4357
4358    @Override
4359    public final void finishHeavyWeightApp() {
4360        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4361                != PackageManager.PERMISSION_GRANTED) {
4362            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4363                    + Binder.getCallingPid()
4364                    + ", uid=" + Binder.getCallingUid()
4365                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4366            Slog.w(TAG, msg);
4367            throw new SecurityException(msg);
4368        }
4369
4370        synchronized(this) {
4371            if (mHeavyWeightProcess == null) {
4372                return;
4373            }
4374
4375            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4376                    mHeavyWeightProcess.activities);
4377            for (int i=0; i<activities.size(); i++) {
4378                ActivityRecord r = activities.get(i);
4379                if (!r.finishing) {
4380                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4381                            null, "finish-heavy", true);
4382                }
4383            }
4384
4385            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4386                    mHeavyWeightProcess.userId, 0));
4387            mHeavyWeightProcess = null;
4388        }
4389    }
4390
4391    @Override
4392    public void crashApplication(int uid, int initialPid, String packageName,
4393            String message) {
4394        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4395                != PackageManager.PERMISSION_GRANTED) {
4396            String msg = "Permission Denial: crashApplication() from pid="
4397                    + Binder.getCallingPid()
4398                    + ", uid=" + Binder.getCallingUid()
4399                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4400            Slog.w(TAG, msg);
4401            throw new SecurityException(msg);
4402        }
4403
4404        synchronized(this) {
4405            ProcessRecord proc = null;
4406
4407            // Figure out which process to kill.  We don't trust that initialPid
4408            // still has any relation to current pids, so must scan through the
4409            // list.
4410            synchronized (mPidsSelfLocked) {
4411                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4412                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4413                    if (p.uid != uid) {
4414                        continue;
4415                    }
4416                    if (p.pid == initialPid) {
4417                        proc = p;
4418                        break;
4419                    }
4420                    if (p.pkgList.containsKey(packageName)) {
4421                        proc = p;
4422                    }
4423                }
4424            }
4425
4426            if (proc == null) {
4427                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4428                        + " initialPid=" + initialPid
4429                        + " packageName=" + packageName);
4430                return;
4431            }
4432
4433            if (proc.thread != null) {
4434                if (proc.pid == Process.myPid()) {
4435                    Log.w(TAG, "crashApplication: trying to crash self!");
4436                    return;
4437                }
4438                long ident = Binder.clearCallingIdentity();
4439                try {
4440                    proc.thread.scheduleCrash(message);
4441                } catch (RemoteException e) {
4442                }
4443                Binder.restoreCallingIdentity(ident);
4444            }
4445        }
4446    }
4447
4448    @Override
4449    public final void finishSubActivity(IBinder token, String resultWho,
4450            int requestCode) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454            if (r != null) {
4455                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4456            }
4457            Binder.restoreCallingIdentity(origId);
4458        }
4459    }
4460
4461    @Override
4462    public boolean finishActivityAffinity(IBinder token) {
4463        synchronized(this) {
4464            final long origId = Binder.clearCallingIdentity();
4465            try {
4466                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4467
4468                ActivityRecord rootR = r.task.getRootActivity();
4469                // Do not allow task to finish in Lock Task mode.
4470                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4471                    if (rootR == r) {
4472                        mStackSupervisor.showLockTaskToast();
4473                        return false;
4474                    }
4475                }
4476                boolean res = false;
4477                if (r != null) {
4478                    res = r.task.stack.finishActivityAffinityLocked(r);
4479                }
4480                return res;
4481            } finally {
4482                Binder.restoreCallingIdentity(origId);
4483            }
4484        }
4485    }
4486
4487    @Override
4488    public void finishVoiceTask(IVoiceInteractionSession session) {
4489        synchronized(this) {
4490            final long origId = Binder.clearCallingIdentity();
4491            try {
4492                mStackSupervisor.finishVoiceTask(session);
4493            } finally {
4494                Binder.restoreCallingIdentity(origId);
4495            }
4496        }
4497
4498    }
4499
4500    @Override
4501    public boolean releaseActivityInstance(IBinder token) {
4502        synchronized(this) {
4503            final long origId = Binder.clearCallingIdentity();
4504            try {
4505                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4506                if (r.task == null || r.task.stack == null) {
4507                    return false;
4508                }
4509                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4510            } finally {
4511                Binder.restoreCallingIdentity(origId);
4512            }
4513        }
4514    }
4515
4516    @Override
4517    public void releaseSomeActivities(IApplicationThread appInt) {
4518        synchronized(this) {
4519            final long origId = Binder.clearCallingIdentity();
4520            try {
4521                ProcessRecord app = getRecordForAppLocked(appInt);
4522                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4523            } finally {
4524                Binder.restoreCallingIdentity(origId);
4525            }
4526        }
4527    }
4528
4529    @Override
4530    public boolean willActivityBeVisible(IBinder token) {
4531        synchronized(this) {
4532            ActivityStack stack = ActivityRecord.getStackLocked(token);
4533            if (stack != null) {
4534                return stack.willActivityBeVisibleLocked(token);
4535            }
4536            return false;
4537        }
4538    }
4539
4540    @Override
4541    public void overridePendingTransition(IBinder token, String packageName,
4542            int enterAnim, int exitAnim) {
4543        synchronized(this) {
4544            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4545            if (self == null) {
4546                return;
4547            }
4548
4549            final long origId = Binder.clearCallingIdentity();
4550
4551            if (self.state == ActivityState.RESUMED
4552                    || self.state == ActivityState.PAUSING) {
4553                mWindowManager.overridePendingAppTransition(packageName,
4554                        enterAnim, exitAnim, null);
4555            }
4556
4557            Binder.restoreCallingIdentity(origId);
4558        }
4559    }
4560
4561    /**
4562     * Main function for removing an existing process from the activity manager
4563     * as a result of that process going away.  Clears out all connections
4564     * to the process.
4565     */
4566    private final void handleAppDiedLocked(ProcessRecord app,
4567            boolean restarting, boolean allowRestart) {
4568        int pid = app.pid;
4569        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4570        if (!kept && !restarting) {
4571            removeLruProcessLocked(app);
4572            if (pid > 0) {
4573                ProcessList.remove(pid);
4574            }
4575        }
4576
4577        if (mProfileProc == app) {
4578            clearProfilerLocked();
4579        }
4580
4581        // Remove this application's activities from active lists.
4582        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4583
4584        app.activities.clear();
4585
4586        if (app.instrumentationClass != null) {
4587            Slog.w(TAG, "Crash of app " + app.processName
4588                  + " running instrumentation " + app.instrumentationClass);
4589            Bundle info = new Bundle();
4590            info.putString("shortMsg", "Process crashed.");
4591            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4592        }
4593
4594        if (!restarting) {
4595            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4596                // If there was nothing to resume, and we are not already
4597                // restarting this process, but there is a visible activity that
4598                // is hosted by the process...  then make sure all visible
4599                // activities are running, taking care of restarting this
4600                // process.
4601                if (hasVisibleActivities) {
4602                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4603                }
4604            }
4605        }
4606    }
4607
4608    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4609        IBinder threadBinder = thread.asBinder();
4610        // Find the application record.
4611        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4612            ProcessRecord rec = mLruProcesses.get(i);
4613            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4614                return i;
4615            }
4616        }
4617        return -1;
4618    }
4619
4620    final ProcessRecord getRecordForAppLocked(
4621            IApplicationThread thread) {
4622        if (thread == null) {
4623            return null;
4624        }
4625
4626        int appIndex = getLRURecordIndexForAppLocked(thread);
4627        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4628    }
4629
4630    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4631        // If there are no longer any background processes running,
4632        // and the app that died was not running instrumentation,
4633        // then tell everyone we are now low on memory.
4634        boolean haveBg = false;
4635        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4636            ProcessRecord rec = mLruProcesses.get(i);
4637            if (rec.thread != null
4638                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4639                haveBg = true;
4640                break;
4641            }
4642        }
4643
4644        if (!haveBg) {
4645            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4646            if (doReport) {
4647                long now = SystemClock.uptimeMillis();
4648                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4649                    doReport = false;
4650                } else {
4651                    mLastMemUsageReportTime = now;
4652                }
4653            }
4654            final ArrayList<ProcessMemInfo> memInfos
4655                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4656            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4657            long now = SystemClock.uptimeMillis();
4658            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4659                ProcessRecord rec = mLruProcesses.get(i);
4660                if (rec == dyingProc || rec.thread == null) {
4661                    continue;
4662                }
4663                if (doReport) {
4664                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4665                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4666                }
4667                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4668                    // The low memory report is overriding any current
4669                    // state for a GC request.  Make sure to do
4670                    // heavy/important/visible/foreground processes first.
4671                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4672                        rec.lastRequestedGc = 0;
4673                    } else {
4674                        rec.lastRequestedGc = rec.lastLowMemory;
4675                    }
4676                    rec.reportLowMemory = true;
4677                    rec.lastLowMemory = now;
4678                    mProcessesToGc.remove(rec);
4679                    addProcessToGcListLocked(rec);
4680                }
4681            }
4682            if (doReport) {
4683                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4684                mHandler.sendMessage(msg);
4685            }
4686            scheduleAppGcsLocked();
4687        }
4688    }
4689
4690    final void appDiedLocked(ProcessRecord app) {
4691       appDiedLocked(app, app.pid, app.thread);
4692    }
4693
4694    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4695        // First check if this ProcessRecord is actually active for the pid.
4696        synchronized (mPidsSelfLocked) {
4697            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4698            if (curProc != app) {
4699                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4700                return;
4701            }
4702        }
4703
4704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4705        synchronized (stats) {
4706            stats.noteProcessDiedLocked(app.info.uid, pid);
4707        }
4708
4709        if (!app.killed) {
4710            Process.killProcessQuiet(pid);
4711            Process.killProcessGroup(app.info.uid, pid);
4712            app.killed = true;
4713        }
4714
4715        // Clean up already done if the process has been re-started.
4716        if (app.pid == pid && app.thread != null &&
4717                app.thread.asBinder() == thread.asBinder()) {
4718            boolean doLowMem = app.instrumentationClass == null;
4719            boolean doOomAdj = doLowMem;
4720            if (!app.killedByAm) {
4721                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4722                        + ") has died");
4723                mAllowLowerMemLevel = true;
4724            } else {
4725                // Note that we always want to do oom adj to update our state with the
4726                // new number of procs.
4727                mAllowLowerMemLevel = false;
4728                doLowMem = false;
4729            }
4730            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4731            if (DEBUG_CLEANUP) Slog.v(
4732                TAG, "Dying app: " + app + ", pid: " + pid
4733                + ", thread: " + thread.asBinder());
4734            handleAppDiedLocked(app, false, true);
4735
4736            if (doOomAdj) {
4737                updateOomAdjLocked();
4738            }
4739            if (doLowMem) {
4740                doLowMemReportIfNeededLocked(app);
4741            }
4742        } else if (app.pid != pid) {
4743            // A new process has already been started.
4744            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4745                    + ") has died and restarted (pid " + app.pid + ").");
4746            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4747        } else if (DEBUG_PROCESSES) {
4748            Slog.d(TAG, "Received spurious death notification for thread "
4749                    + thread.asBinder());
4750        }
4751    }
4752
4753    /**
4754     * If a stack trace dump file is configured, dump process stack traces.
4755     * @param clearTraces causes the dump file to be erased prior to the new
4756     *    traces being written, if true; when false, the new traces will be
4757     *    appended to any existing file content.
4758     * @param firstPids of dalvik VM processes to dump stack traces for first
4759     * @param lastPids of dalvik VM processes to dump stack traces for last
4760     * @param nativeProcs optional list of native process names to dump stack crawls
4761     * @return file containing stack traces, or null if no dump file is configured
4762     */
4763    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4764            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4765        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4766        if (tracesPath == null || tracesPath.length() == 0) {
4767            return null;
4768        }
4769
4770        File tracesFile = new File(tracesPath);
4771        try {
4772            File tracesDir = tracesFile.getParentFile();
4773            if (!tracesDir.exists()) {
4774                tracesDir.mkdirs();
4775                if (!SELinux.restorecon(tracesDir)) {
4776                    return null;
4777                }
4778            }
4779            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4780
4781            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4782            tracesFile.createNewFile();
4783            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4784        } catch (IOException e) {
4785            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4786            return null;
4787        }
4788
4789        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4790        return tracesFile;
4791    }
4792
4793    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4794            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4795        // Use a FileObserver to detect when traces finish writing.
4796        // The order of traces is considered important to maintain for legibility.
4797        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4798            @Override
4799            public synchronized void onEvent(int event, String path) { notify(); }
4800        };
4801
4802        try {
4803            observer.startWatching();
4804
4805            // First collect all of the stacks of the most important pids.
4806            if (firstPids != null) {
4807                try {
4808                    int num = firstPids.size();
4809                    for (int i = 0; i < num; i++) {
4810                        synchronized (observer) {
4811                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4812                            observer.wait(200);  // Wait for write-close, give up after 200msec
4813                        }
4814                    }
4815                } catch (InterruptedException e) {
4816                    Slog.wtf(TAG, e);
4817                }
4818            }
4819
4820            // Next collect the stacks of the native pids
4821            if (nativeProcs != null) {
4822                int[] pids = Process.getPidsForCommands(nativeProcs);
4823                if (pids != null) {
4824                    for (int pid : pids) {
4825                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4826                    }
4827                }
4828            }
4829
4830            // Lastly, measure CPU usage.
4831            if (processCpuTracker != null) {
4832                processCpuTracker.init();
4833                System.gc();
4834                processCpuTracker.update();
4835                try {
4836                    synchronized (processCpuTracker) {
4837                        processCpuTracker.wait(500); // measure over 1/2 second.
4838                    }
4839                } catch (InterruptedException e) {
4840                }
4841                processCpuTracker.update();
4842
4843                // We'll take the stack crawls of just the top apps using CPU.
4844                final int N = processCpuTracker.countWorkingStats();
4845                int numProcs = 0;
4846                for (int i=0; i<N && numProcs<5; i++) {
4847                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4848                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4849                        numProcs++;
4850                        try {
4851                            synchronized (observer) {
4852                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4853                                observer.wait(200);  // Wait for write-close, give up after 200msec
4854                            }
4855                        } catch (InterruptedException e) {
4856                            Slog.wtf(TAG, e);
4857                        }
4858
4859                    }
4860                }
4861            }
4862        } finally {
4863            observer.stopWatching();
4864        }
4865    }
4866
4867    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4868        if (true || IS_USER_BUILD) {
4869            return;
4870        }
4871        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4872        if (tracesPath == null || tracesPath.length() == 0) {
4873            return;
4874        }
4875
4876        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4877        StrictMode.allowThreadDiskWrites();
4878        try {
4879            final File tracesFile = new File(tracesPath);
4880            final File tracesDir = tracesFile.getParentFile();
4881            final File tracesTmp = new File(tracesDir, "__tmp__");
4882            try {
4883                if (!tracesDir.exists()) {
4884                    tracesDir.mkdirs();
4885                    if (!SELinux.restorecon(tracesDir.getPath())) {
4886                        return;
4887                    }
4888                }
4889                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4890
4891                if (tracesFile.exists()) {
4892                    tracesTmp.delete();
4893                    tracesFile.renameTo(tracesTmp);
4894                }
4895                StringBuilder sb = new StringBuilder();
4896                Time tobj = new Time();
4897                tobj.set(System.currentTimeMillis());
4898                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4899                sb.append(": ");
4900                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4901                sb.append(" since ");
4902                sb.append(msg);
4903                FileOutputStream fos = new FileOutputStream(tracesFile);
4904                fos.write(sb.toString().getBytes());
4905                if (app == null) {
4906                    fos.write("\n*** No application process!".getBytes());
4907                }
4908                fos.close();
4909                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4910            } catch (IOException e) {
4911                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4912                return;
4913            }
4914
4915            if (app != null) {
4916                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4917                firstPids.add(app.pid);
4918                dumpStackTraces(tracesPath, firstPids, null, null, null);
4919            }
4920
4921            File lastTracesFile = null;
4922            File curTracesFile = null;
4923            for (int i=9; i>=0; i--) {
4924                String name = String.format(Locale.US, "slow%02d.txt", i);
4925                curTracesFile = new File(tracesDir, name);
4926                if (curTracesFile.exists()) {
4927                    if (lastTracesFile != null) {
4928                        curTracesFile.renameTo(lastTracesFile);
4929                    } else {
4930                        curTracesFile.delete();
4931                    }
4932                }
4933                lastTracesFile = curTracesFile;
4934            }
4935            tracesFile.renameTo(curTracesFile);
4936            if (tracesTmp.exists()) {
4937                tracesTmp.renameTo(tracesFile);
4938            }
4939        } finally {
4940            StrictMode.setThreadPolicy(oldPolicy);
4941        }
4942    }
4943
4944    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4945            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4946        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4947        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4948
4949        if (mController != null) {
4950            try {
4951                // 0 == continue, -1 = kill process immediately
4952                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4953                if (res < 0 && app.pid != MY_PID) {
4954                    app.kill("anr", true);
4955                }
4956            } catch (RemoteException e) {
4957                mController = null;
4958                Watchdog.getInstance().setActivityController(null);
4959            }
4960        }
4961
4962        long anrTime = SystemClock.uptimeMillis();
4963        if (MONITOR_CPU_USAGE) {
4964            updateCpuStatsNow();
4965        }
4966
4967        synchronized (this) {
4968            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4969            if (mShuttingDown) {
4970                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4971                return;
4972            } else if (app.notResponding) {
4973                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4974                return;
4975            } else if (app.crashing) {
4976                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4977                return;
4978            }
4979
4980            // In case we come through here for the same app before completing
4981            // this one, mark as anring now so we will bail out.
4982            app.notResponding = true;
4983
4984            // Log the ANR to the event log.
4985            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4986                    app.processName, app.info.flags, annotation);
4987
4988            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4989            firstPids.add(app.pid);
4990
4991            int parentPid = app.pid;
4992            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4993            if (parentPid != app.pid) firstPids.add(parentPid);
4994
4995            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4996
4997            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4998                ProcessRecord r = mLruProcesses.get(i);
4999                if (r != null && r.thread != null) {
5000                    int pid = r.pid;
5001                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5002                        if (r.persistent) {
5003                            firstPids.add(pid);
5004                        } else {
5005                            lastPids.put(pid, Boolean.TRUE);
5006                        }
5007                    }
5008                }
5009            }
5010        }
5011
5012        // Log the ANR to the main log.
5013        StringBuilder info = new StringBuilder();
5014        info.setLength(0);
5015        info.append("ANR in ").append(app.processName);
5016        if (activity != null && activity.shortComponentName != null) {
5017            info.append(" (").append(activity.shortComponentName).append(")");
5018        }
5019        info.append("\n");
5020        info.append("PID: ").append(app.pid).append("\n");
5021        if (annotation != null) {
5022            info.append("Reason: ").append(annotation).append("\n");
5023        }
5024        if (parent != null && parent != activity) {
5025            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5026        }
5027
5028        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5029
5030        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5031                NATIVE_STACKS_OF_INTEREST);
5032
5033        String cpuInfo = null;
5034        if (MONITOR_CPU_USAGE) {
5035            updateCpuStatsNow();
5036            synchronized (mProcessCpuTracker) {
5037                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5038            }
5039            info.append(processCpuTracker.printCurrentLoad());
5040            info.append(cpuInfo);
5041        }
5042
5043        info.append(processCpuTracker.printCurrentState(anrTime));
5044
5045        Slog.e(TAG, info.toString());
5046        if (tracesFile == null) {
5047            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5048            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5049        }
5050
5051        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5052                cpuInfo, tracesFile, null);
5053
5054        if (mController != null) {
5055            try {
5056                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5057                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5058                if (res != 0) {
5059                    if (res < 0 && app.pid != MY_PID) {
5060                        app.kill("anr", true);
5061                    } else {
5062                        synchronized (this) {
5063                            mServices.scheduleServiceTimeoutLocked(app);
5064                        }
5065                    }
5066                    return;
5067                }
5068            } catch (RemoteException e) {
5069                mController = null;
5070                Watchdog.getInstance().setActivityController(null);
5071            }
5072        }
5073
5074        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5075        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5076                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5077
5078        synchronized (this) {
5079            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5080
5081            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5082                app.kill("bg anr", true);
5083                return;
5084            }
5085
5086            // Set the app's notResponding state, and look up the errorReportReceiver
5087            makeAppNotRespondingLocked(app,
5088                    activity != null ? activity.shortComponentName : null,
5089                    annotation != null ? "ANR " + annotation : "ANR",
5090                    info.toString());
5091
5092            // Bring up the infamous App Not Responding dialog
5093            Message msg = Message.obtain();
5094            HashMap<String, Object> map = new HashMap<String, Object>();
5095            msg.what = SHOW_NOT_RESPONDING_MSG;
5096            msg.obj = map;
5097            msg.arg1 = aboveSystem ? 1 : 0;
5098            map.put("app", app);
5099            if (activity != null) {
5100                map.put("activity", activity);
5101            }
5102
5103            mHandler.sendMessage(msg);
5104        }
5105    }
5106
5107    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5108        if (!mLaunchWarningShown) {
5109            mLaunchWarningShown = true;
5110            mHandler.post(new Runnable() {
5111                @Override
5112                public void run() {
5113                    synchronized (ActivityManagerService.this) {
5114                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5115                        d.show();
5116                        mHandler.postDelayed(new Runnable() {
5117                            @Override
5118                            public void run() {
5119                                synchronized (ActivityManagerService.this) {
5120                                    d.dismiss();
5121                                    mLaunchWarningShown = false;
5122                                }
5123                            }
5124                        }, 4000);
5125                    }
5126                }
5127            });
5128        }
5129    }
5130
5131    @Override
5132    public boolean clearApplicationUserData(final String packageName,
5133            final IPackageDataObserver observer, int userId) {
5134        enforceNotIsolatedCaller("clearApplicationUserData");
5135        int uid = Binder.getCallingUid();
5136        int pid = Binder.getCallingPid();
5137        userId = handleIncomingUser(pid, uid,
5138                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5139        long callingId = Binder.clearCallingIdentity();
5140        try {
5141            IPackageManager pm = AppGlobals.getPackageManager();
5142            int pkgUid = -1;
5143            synchronized(this) {
5144                try {
5145                    pkgUid = pm.getPackageUid(packageName, userId);
5146                } catch (RemoteException e) {
5147                }
5148                if (pkgUid == -1) {
5149                    Slog.w(TAG, "Invalid packageName: " + packageName);
5150                    if (observer != null) {
5151                        try {
5152                            observer.onRemoveCompleted(packageName, false);
5153                        } catch (RemoteException e) {
5154                            Slog.i(TAG, "Observer no longer exists.");
5155                        }
5156                    }
5157                    return false;
5158                }
5159                if (uid == pkgUid || checkComponentPermission(
5160                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5161                        pid, uid, -1, true)
5162                        == PackageManager.PERMISSION_GRANTED) {
5163                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5164                } else {
5165                    throw new SecurityException("PID " + pid + " does not have permission "
5166                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5167                                    + " of package " + packageName);
5168                }
5169
5170                // Remove all tasks match the cleared application package and user
5171                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5172                    final TaskRecord tr = mRecentTasks.get(i);
5173                    final String taskPackageName =
5174                            tr.getBaseIntent().getComponent().getPackageName();
5175                    if (tr.userId != userId) continue;
5176                    if (!taskPackageName.equals(packageName)) continue;
5177                    removeTaskByIdLocked(tr.taskId, false);
5178                }
5179            }
5180
5181            try {
5182                // Clear application user data
5183                pm.clearApplicationUserData(packageName, observer, userId);
5184
5185                synchronized(this) {
5186                    // Remove all permissions granted from/to this package
5187                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5188                }
5189
5190                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5191                        Uri.fromParts("package", packageName, null));
5192                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5193                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5194                        null, null, 0, null, null, null, false, false, userId);
5195            } catch (RemoteException e) {
5196            }
5197        } finally {
5198            Binder.restoreCallingIdentity(callingId);
5199        }
5200        return true;
5201    }
5202
5203    @Override
5204    public void killBackgroundProcesses(final String packageName, int userId) {
5205        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5206                != PackageManager.PERMISSION_GRANTED &&
5207                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5208                        != PackageManager.PERMISSION_GRANTED) {
5209            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5210                    + Binder.getCallingPid()
5211                    + ", uid=" + Binder.getCallingUid()
5212                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5213            Slog.w(TAG, msg);
5214            throw new SecurityException(msg);
5215        }
5216
5217        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5218                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5219        long callingId = Binder.clearCallingIdentity();
5220        try {
5221            IPackageManager pm = AppGlobals.getPackageManager();
5222            synchronized(this) {
5223                int appId = -1;
5224                try {
5225                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5226                } catch (RemoteException e) {
5227                }
5228                if (appId == -1) {
5229                    Slog.w(TAG, "Invalid packageName: " + packageName);
5230                    return;
5231                }
5232                killPackageProcessesLocked(packageName, appId, userId,
5233                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5234            }
5235        } finally {
5236            Binder.restoreCallingIdentity(callingId);
5237        }
5238    }
5239
5240    @Override
5241    public void killAllBackgroundProcesses() {
5242        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5243                != PackageManager.PERMISSION_GRANTED) {
5244            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5245                    + Binder.getCallingPid()
5246                    + ", uid=" + Binder.getCallingUid()
5247                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5248            Slog.w(TAG, msg);
5249            throw new SecurityException(msg);
5250        }
5251
5252        long callingId = Binder.clearCallingIdentity();
5253        try {
5254            synchronized(this) {
5255                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5256                final int NP = mProcessNames.getMap().size();
5257                for (int ip=0; ip<NP; ip++) {
5258                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5259                    final int NA = apps.size();
5260                    for (int ia=0; ia<NA; ia++) {
5261                        ProcessRecord app = apps.valueAt(ia);
5262                        if (app.persistent) {
5263                            // we don't kill persistent processes
5264                            continue;
5265                        }
5266                        if (app.removed) {
5267                            procs.add(app);
5268                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5269                            app.removed = true;
5270                            procs.add(app);
5271                        }
5272                    }
5273                }
5274
5275                int N = procs.size();
5276                for (int i=0; i<N; i++) {
5277                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5278                }
5279                mAllowLowerMemLevel = true;
5280                updateOomAdjLocked();
5281                doLowMemReportIfNeededLocked(null);
5282            }
5283        } finally {
5284            Binder.restoreCallingIdentity(callingId);
5285        }
5286    }
5287
5288    @Override
5289    public void forceStopPackage(final String packageName, int userId) {
5290        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5291                != PackageManager.PERMISSION_GRANTED) {
5292            String msg = "Permission Denial: forceStopPackage() from pid="
5293                    + Binder.getCallingPid()
5294                    + ", uid=" + Binder.getCallingUid()
5295                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5296            Slog.w(TAG, msg);
5297            throw new SecurityException(msg);
5298        }
5299        final int callingPid = Binder.getCallingPid();
5300        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5301                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5302        long callingId = Binder.clearCallingIdentity();
5303        try {
5304            IPackageManager pm = AppGlobals.getPackageManager();
5305            synchronized(this) {
5306                int[] users = userId == UserHandle.USER_ALL
5307                        ? getUsersLocked() : new int[] { userId };
5308                for (int user : users) {
5309                    int pkgUid = -1;
5310                    try {
5311                        pkgUid = pm.getPackageUid(packageName, user);
5312                    } catch (RemoteException e) {
5313                    }
5314                    if (pkgUid == -1) {
5315                        Slog.w(TAG, "Invalid packageName: " + packageName);
5316                        continue;
5317                    }
5318                    try {
5319                        pm.setPackageStoppedState(packageName, true, user);
5320                    } catch (RemoteException e) {
5321                    } catch (IllegalArgumentException e) {
5322                        Slog.w(TAG, "Failed trying to unstop package "
5323                                + packageName + ": " + e);
5324                    }
5325                    if (isUserRunningLocked(user, false)) {
5326                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5327                    }
5328                }
5329            }
5330        } finally {
5331            Binder.restoreCallingIdentity(callingId);
5332        }
5333    }
5334
5335    @Override
5336    public void addPackageDependency(String packageName) {
5337        synchronized (this) {
5338            int callingPid = Binder.getCallingPid();
5339            if (callingPid == Process.myPid()) {
5340                //  Yeah, um, no.
5341                return;
5342            }
5343            ProcessRecord proc;
5344            synchronized (mPidsSelfLocked) {
5345                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5346            }
5347            if (proc != null) {
5348                if (proc.pkgDeps == null) {
5349                    proc.pkgDeps = new ArraySet<String>(1);
5350                }
5351                proc.pkgDeps.add(packageName);
5352            }
5353        }
5354    }
5355
5356    /*
5357     * The pkg name and app id have to be specified.
5358     */
5359    @Override
5360    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5361        if (pkg == null) {
5362            return;
5363        }
5364        // Make sure the uid is valid.
5365        if (appid < 0) {
5366            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5367            return;
5368        }
5369        int callerUid = Binder.getCallingUid();
5370        // Only the system server can kill an application
5371        if (callerUid == Process.SYSTEM_UID) {
5372            // Post an aysnc message to kill the application
5373            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5374            msg.arg1 = appid;
5375            msg.arg2 = 0;
5376            Bundle bundle = new Bundle();
5377            bundle.putString("pkg", pkg);
5378            bundle.putString("reason", reason);
5379            msg.obj = bundle;
5380            mHandler.sendMessage(msg);
5381        } else {
5382            throw new SecurityException(callerUid + " cannot kill pkg: " +
5383                    pkg);
5384        }
5385    }
5386
5387    @Override
5388    public void closeSystemDialogs(String reason) {
5389        enforceNotIsolatedCaller("closeSystemDialogs");
5390
5391        final int pid = Binder.getCallingPid();
5392        final int uid = Binder.getCallingUid();
5393        final long origId = Binder.clearCallingIdentity();
5394        try {
5395            synchronized (this) {
5396                // Only allow this from foreground processes, so that background
5397                // applications can't abuse it to prevent system UI from being shown.
5398                if (uid >= Process.FIRST_APPLICATION_UID) {
5399                    ProcessRecord proc;
5400                    synchronized (mPidsSelfLocked) {
5401                        proc = mPidsSelfLocked.get(pid);
5402                    }
5403                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5404                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5405                                + " from background process " + proc);
5406                        return;
5407                    }
5408                }
5409                closeSystemDialogsLocked(reason);
5410            }
5411        } finally {
5412            Binder.restoreCallingIdentity(origId);
5413        }
5414    }
5415
5416    void closeSystemDialogsLocked(String reason) {
5417        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5418        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5419                | Intent.FLAG_RECEIVER_FOREGROUND);
5420        if (reason != null) {
5421            intent.putExtra("reason", reason);
5422        }
5423        mWindowManager.closeSystemDialogs(reason);
5424
5425        mStackSupervisor.closeSystemDialogsLocked();
5426
5427        broadcastIntentLocked(null, null, intent, null,
5428                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5429                Process.SYSTEM_UID, UserHandle.USER_ALL);
5430    }
5431
5432    @Override
5433    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5434        enforceNotIsolatedCaller("getProcessMemoryInfo");
5435        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5436        for (int i=pids.length-1; i>=0; i--) {
5437            ProcessRecord proc;
5438            int oomAdj;
5439            synchronized (this) {
5440                synchronized (mPidsSelfLocked) {
5441                    proc = mPidsSelfLocked.get(pids[i]);
5442                    oomAdj = proc != null ? proc.setAdj : 0;
5443                }
5444            }
5445            infos[i] = new Debug.MemoryInfo();
5446            Debug.getMemoryInfo(pids[i], infos[i]);
5447            if (proc != null) {
5448                synchronized (this) {
5449                    if (proc.thread != null && proc.setAdj == oomAdj) {
5450                        // Record this for posterity if the process has been stable.
5451                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5452                                infos[i].getTotalUss(), false, proc.pkgList);
5453                    }
5454                }
5455            }
5456        }
5457        return infos;
5458    }
5459
5460    @Override
5461    public long[] getProcessPss(int[] pids) {
5462        enforceNotIsolatedCaller("getProcessPss");
5463        long[] pss = new long[pids.length];
5464        for (int i=pids.length-1; i>=0; i--) {
5465            ProcessRecord proc;
5466            int oomAdj;
5467            synchronized (this) {
5468                synchronized (mPidsSelfLocked) {
5469                    proc = mPidsSelfLocked.get(pids[i]);
5470                    oomAdj = proc != null ? proc.setAdj : 0;
5471                }
5472            }
5473            long[] tmpUss = new long[1];
5474            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5475            if (proc != null) {
5476                synchronized (this) {
5477                    if (proc.thread != null && proc.setAdj == oomAdj) {
5478                        // Record this for posterity if the process has been stable.
5479                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5480                    }
5481                }
5482            }
5483        }
5484        return pss;
5485    }
5486
5487    @Override
5488    public void killApplicationProcess(String processName, int uid) {
5489        if (processName == null) {
5490            return;
5491        }
5492
5493        int callerUid = Binder.getCallingUid();
5494        // Only the system server can kill an application
5495        if (callerUid == Process.SYSTEM_UID) {
5496            synchronized (this) {
5497                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5498                if (app != null && app.thread != null) {
5499                    try {
5500                        app.thread.scheduleSuicide();
5501                    } catch (RemoteException e) {
5502                        // If the other end already died, then our work here is done.
5503                    }
5504                } else {
5505                    Slog.w(TAG, "Process/uid not found attempting kill of "
5506                            + processName + " / " + uid);
5507                }
5508            }
5509        } else {
5510            throw new SecurityException(callerUid + " cannot kill app process: " +
5511                    processName);
5512        }
5513    }
5514
5515    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5516        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5517                false, true, false, false, UserHandle.getUserId(uid), reason);
5518        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5519                Uri.fromParts("package", packageName, null));
5520        if (!mProcessesReady) {
5521            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5522                    | Intent.FLAG_RECEIVER_FOREGROUND);
5523        }
5524        intent.putExtra(Intent.EXTRA_UID, uid);
5525        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5526        broadcastIntentLocked(null, null, intent,
5527                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5528                false, false,
5529                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5530    }
5531
5532    private void forceStopUserLocked(int userId, String reason) {
5533        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5534        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5535        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5536                | Intent.FLAG_RECEIVER_FOREGROUND);
5537        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5538        broadcastIntentLocked(null, null, intent,
5539                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5540                false, false,
5541                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5542    }
5543
5544    private final boolean killPackageProcessesLocked(String packageName, int appId,
5545            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5546            boolean doit, boolean evenPersistent, String reason) {
5547        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5548
5549        // Remove all processes this package may have touched: all with the
5550        // same UID (except for the system or root user), and all whose name
5551        // matches the package name.
5552        final int NP = mProcessNames.getMap().size();
5553        for (int ip=0; ip<NP; ip++) {
5554            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5555            final int NA = apps.size();
5556            for (int ia=0; ia<NA; ia++) {
5557                ProcessRecord app = apps.valueAt(ia);
5558                if (app.persistent && !evenPersistent) {
5559                    // we don't kill persistent processes
5560                    continue;
5561                }
5562                if (app.removed) {
5563                    if (doit) {
5564                        procs.add(app);
5565                    }
5566                    continue;
5567                }
5568
5569                // Skip process if it doesn't meet our oom adj requirement.
5570                if (app.setAdj < minOomAdj) {
5571                    continue;
5572                }
5573
5574                // If no package is specified, we call all processes under the
5575                // give user id.
5576                if (packageName == null) {
5577                    if (app.userId != userId) {
5578                        continue;
5579                    }
5580                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5581                        continue;
5582                    }
5583                // Package has been specified, we want to hit all processes
5584                // that match it.  We need to qualify this by the processes
5585                // that are running under the specified app and user ID.
5586                } else {
5587                    final boolean isDep = app.pkgDeps != null
5588                            && app.pkgDeps.contains(packageName);
5589                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5590                        continue;
5591                    }
5592                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5593                        continue;
5594                    }
5595                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5596                        continue;
5597                    }
5598                }
5599
5600                // Process has passed all conditions, kill it!
5601                if (!doit) {
5602                    return true;
5603                }
5604                app.removed = true;
5605                procs.add(app);
5606            }
5607        }
5608
5609        int N = procs.size();
5610        for (int i=0; i<N; i++) {
5611            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5612        }
5613        updateOomAdjLocked();
5614        return N > 0;
5615    }
5616
5617    private final boolean forceStopPackageLocked(String name, int appId,
5618            boolean callerWillRestart, boolean purgeCache, boolean doit,
5619            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5620        int i;
5621        int N;
5622
5623        if (userId == UserHandle.USER_ALL && name == null) {
5624            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5625        }
5626
5627        if (appId < 0 && name != null) {
5628            try {
5629                appId = UserHandle.getAppId(
5630                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5631            } catch (RemoteException e) {
5632            }
5633        }
5634
5635        if (doit) {
5636            if (name != null) {
5637                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5638                        + " user=" + userId + ": " + reason);
5639            } else {
5640                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5641            }
5642
5643            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5644            for (int ip=pmap.size()-1; ip>=0; ip--) {
5645                SparseArray<Long> ba = pmap.valueAt(ip);
5646                for (i=ba.size()-1; i>=0; i--) {
5647                    boolean remove = false;
5648                    final int entUid = ba.keyAt(i);
5649                    if (name != null) {
5650                        if (userId == UserHandle.USER_ALL) {
5651                            if (UserHandle.getAppId(entUid) == appId) {
5652                                remove = true;
5653                            }
5654                        } else {
5655                            if (entUid == UserHandle.getUid(userId, appId)) {
5656                                remove = true;
5657                            }
5658                        }
5659                    } else if (UserHandle.getUserId(entUid) == userId) {
5660                        remove = true;
5661                    }
5662                    if (remove) {
5663                        ba.removeAt(i);
5664                    }
5665                }
5666                if (ba.size() == 0) {
5667                    pmap.removeAt(ip);
5668                }
5669            }
5670        }
5671
5672        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5673                -100, callerWillRestart, true, doit, evenPersistent,
5674                name == null ? ("stop user " + userId) : ("stop " + name));
5675
5676        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5677            if (!doit) {
5678                return true;
5679            }
5680            didSomething = true;
5681        }
5682
5683        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5684            if (!doit) {
5685                return true;
5686            }
5687            didSomething = true;
5688        }
5689
5690        if (name == null) {
5691            // Remove all sticky broadcasts from this user.
5692            mStickyBroadcasts.remove(userId);
5693        }
5694
5695        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5696        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5697                userId, providers)) {
5698            if (!doit) {
5699                return true;
5700            }
5701            didSomething = true;
5702        }
5703        N = providers.size();
5704        for (i=0; i<N; i++) {
5705            removeDyingProviderLocked(null, providers.get(i), true);
5706        }
5707
5708        // Remove transient permissions granted from/to this package/user
5709        removeUriPermissionsForPackageLocked(name, userId, false);
5710
5711        if (name == null || uninstalling) {
5712            // Remove pending intents.  For now we only do this when force
5713            // stopping users, because we have some problems when doing this
5714            // for packages -- app widgets are not currently cleaned up for
5715            // such packages, so they can be left with bad pending intents.
5716            if (mIntentSenderRecords.size() > 0) {
5717                Iterator<WeakReference<PendingIntentRecord>> it
5718                        = mIntentSenderRecords.values().iterator();
5719                while (it.hasNext()) {
5720                    WeakReference<PendingIntentRecord> wpir = it.next();
5721                    if (wpir == null) {
5722                        it.remove();
5723                        continue;
5724                    }
5725                    PendingIntentRecord pir = wpir.get();
5726                    if (pir == null) {
5727                        it.remove();
5728                        continue;
5729                    }
5730                    if (name == null) {
5731                        // Stopping user, remove all objects for the user.
5732                        if (pir.key.userId != userId) {
5733                            // Not the same user, skip it.
5734                            continue;
5735                        }
5736                    } else {
5737                        if (UserHandle.getAppId(pir.uid) != appId) {
5738                            // Different app id, skip it.
5739                            continue;
5740                        }
5741                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5742                            // Different user, skip it.
5743                            continue;
5744                        }
5745                        if (!pir.key.packageName.equals(name)) {
5746                            // Different package, skip it.
5747                            continue;
5748                        }
5749                    }
5750                    if (!doit) {
5751                        return true;
5752                    }
5753                    didSomething = true;
5754                    it.remove();
5755                    pir.canceled = true;
5756                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5757                        pir.key.activity.pendingResults.remove(pir.ref);
5758                    }
5759                }
5760            }
5761        }
5762
5763        if (doit) {
5764            if (purgeCache && name != null) {
5765                AttributeCache ac = AttributeCache.instance();
5766                if (ac != null) {
5767                    ac.removePackage(name);
5768                }
5769            }
5770            if (mBooted) {
5771                mStackSupervisor.resumeTopActivitiesLocked();
5772                mStackSupervisor.scheduleIdleLocked();
5773            }
5774        }
5775
5776        return didSomething;
5777    }
5778
5779    private final boolean removeProcessLocked(ProcessRecord app,
5780            boolean callerWillRestart, boolean allowRestart, String reason) {
5781        final String name = app.processName;
5782        final int uid = app.uid;
5783        if (DEBUG_PROCESSES) Slog.d(
5784            TAG, "Force removing proc " + app.toShortString() + " (" + name
5785            + "/" + uid + ")");
5786
5787        mProcessNames.remove(name, uid);
5788        mIsolatedProcesses.remove(app.uid);
5789        if (mHeavyWeightProcess == app) {
5790            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5791                    mHeavyWeightProcess.userId, 0));
5792            mHeavyWeightProcess = null;
5793        }
5794        boolean needRestart = false;
5795        if (app.pid > 0 && app.pid != MY_PID) {
5796            int pid = app.pid;
5797            synchronized (mPidsSelfLocked) {
5798                mPidsSelfLocked.remove(pid);
5799                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5800            }
5801            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5802            if (app.isolated) {
5803                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5804            }
5805            app.kill(reason, true);
5806            handleAppDiedLocked(app, true, allowRestart);
5807            removeLruProcessLocked(app);
5808
5809            if (app.persistent && !app.isolated) {
5810                if (!callerWillRestart) {
5811                    addAppLocked(app.info, false, null /* ABI override */);
5812                } else {
5813                    needRestart = true;
5814                }
5815            }
5816        } else {
5817            mRemovedProcesses.add(app);
5818        }
5819
5820        return needRestart;
5821    }
5822
5823    private final void processStartTimedOutLocked(ProcessRecord app) {
5824        final int pid = app.pid;
5825        boolean gone = false;
5826        synchronized (mPidsSelfLocked) {
5827            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5828            if (knownApp != null && knownApp.thread == null) {
5829                mPidsSelfLocked.remove(pid);
5830                gone = true;
5831            }
5832        }
5833
5834        if (gone) {
5835            Slog.w(TAG, "Process " + app + " failed to attach");
5836            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5837                    pid, app.uid, app.processName);
5838            mProcessNames.remove(app.processName, app.uid);
5839            mIsolatedProcesses.remove(app.uid);
5840            if (mHeavyWeightProcess == app) {
5841                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5842                        mHeavyWeightProcess.userId, 0));
5843                mHeavyWeightProcess = null;
5844            }
5845            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5846            if (app.isolated) {
5847                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5848            }
5849            // Take care of any launching providers waiting for this process.
5850            checkAppInLaunchingProvidersLocked(app, true);
5851            // Take care of any services that are waiting for the process.
5852            mServices.processStartTimedOutLocked(app);
5853            app.kill("start timeout", true);
5854            removeLruProcessLocked(app);
5855            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5856                Slog.w(TAG, "Unattached app died before backup, skipping");
5857                try {
5858                    IBackupManager bm = IBackupManager.Stub.asInterface(
5859                            ServiceManager.getService(Context.BACKUP_SERVICE));
5860                    bm.agentDisconnected(app.info.packageName);
5861                } catch (RemoteException e) {
5862                    // Can't happen; the backup manager is local
5863                }
5864            }
5865            if (isPendingBroadcastProcessLocked(pid)) {
5866                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5867                skipPendingBroadcastLocked(pid);
5868            }
5869        } else {
5870            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5871        }
5872    }
5873
5874    private final boolean attachApplicationLocked(IApplicationThread thread,
5875            int pid) {
5876
5877        // Find the application record that is being attached...  either via
5878        // the pid if we are running in multiple processes, or just pull the
5879        // next app record if we are emulating process with anonymous threads.
5880        ProcessRecord app;
5881        if (pid != MY_PID && pid >= 0) {
5882            synchronized (mPidsSelfLocked) {
5883                app = mPidsSelfLocked.get(pid);
5884            }
5885        } else {
5886            app = null;
5887        }
5888
5889        if (app == null) {
5890            Slog.w(TAG, "No pending application record for pid " + pid
5891                    + " (IApplicationThread " + thread + "); dropping process");
5892            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5893            if (pid > 0 && pid != MY_PID) {
5894                Process.killProcessQuiet(pid);
5895                //TODO: Process.killProcessGroup(app.info.uid, pid);
5896            } else {
5897                try {
5898                    thread.scheduleExit();
5899                } catch (Exception e) {
5900                    // Ignore exceptions.
5901                }
5902            }
5903            return false;
5904        }
5905
5906        // If this application record is still attached to a previous
5907        // process, clean it up now.
5908        if (app.thread != null) {
5909            handleAppDiedLocked(app, true, true);
5910        }
5911
5912        // Tell the process all about itself.
5913
5914        if (localLOGV) Slog.v(
5915                TAG, "Binding process pid " + pid + " to record " + app);
5916
5917        final String processName = app.processName;
5918        try {
5919            AppDeathRecipient adr = new AppDeathRecipient(
5920                    app, pid, thread);
5921            thread.asBinder().linkToDeath(adr, 0);
5922            app.deathRecipient = adr;
5923        } catch (RemoteException e) {
5924            app.resetPackageList(mProcessStats);
5925            startProcessLocked(app, "link fail", processName);
5926            return false;
5927        }
5928
5929        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5930
5931        app.makeActive(thread, mProcessStats);
5932        app.curAdj = app.setAdj = -100;
5933        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5934        app.forcingToForeground = null;
5935        updateProcessForegroundLocked(app, false, false);
5936        app.hasShownUi = false;
5937        app.debugging = false;
5938        app.cached = false;
5939        app.killedByAm = false;
5940
5941        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5942
5943        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5944        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5945
5946        if (!normalMode) {
5947            Slog.i(TAG, "Launching preboot mode app: " + app);
5948        }
5949
5950        if (localLOGV) Slog.v(
5951            TAG, "New app record " + app
5952            + " thread=" + thread.asBinder() + " pid=" + pid);
5953        try {
5954            int testMode = IApplicationThread.DEBUG_OFF;
5955            if (mDebugApp != null && mDebugApp.equals(processName)) {
5956                testMode = mWaitForDebugger
5957                    ? IApplicationThread.DEBUG_WAIT
5958                    : IApplicationThread.DEBUG_ON;
5959                app.debugging = true;
5960                if (mDebugTransient) {
5961                    mDebugApp = mOrigDebugApp;
5962                    mWaitForDebugger = mOrigWaitForDebugger;
5963                }
5964            }
5965            String profileFile = app.instrumentationProfileFile;
5966            ParcelFileDescriptor profileFd = null;
5967            int samplingInterval = 0;
5968            boolean profileAutoStop = false;
5969            if (mProfileApp != null && mProfileApp.equals(processName)) {
5970                mProfileProc = app;
5971                profileFile = mProfileFile;
5972                profileFd = mProfileFd;
5973                samplingInterval = mSamplingInterval;
5974                profileAutoStop = mAutoStopProfiler;
5975            }
5976            boolean enableOpenGlTrace = false;
5977            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5978                enableOpenGlTrace = true;
5979                mOpenGlTraceApp = null;
5980            }
5981
5982            // If the app is being launched for restore or full backup, set it up specially
5983            boolean isRestrictedBackupMode = false;
5984            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5985                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5986                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5987                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5988            }
5989
5990            ensurePackageDexOpt(app.instrumentationInfo != null
5991                    ? app.instrumentationInfo.packageName
5992                    : app.info.packageName);
5993            if (app.instrumentationClass != null) {
5994                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5995            }
5996            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5997                    + processName + " with config " + mConfiguration);
5998            ApplicationInfo appInfo = app.instrumentationInfo != null
5999                    ? app.instrumentationInfo : app.info;
6000            app.compat = compatibilityInfoForPackageLocked(appInfo);
6001            if (profileFd != null) {
6002                profileFd = profileFd.dup();
6003            }
6004            ProfilerInfo profilerInfo = profileFile == null ? null
6005                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6006            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6007                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6008                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6009                    isRestrictedBackupMode || !normalMode, app.persistent,
6010                    new Configuration(mConfiguration), app.compat,
6011                    getCommonServicesLocked(app.isolated),
6012                    mCoreSettingsObserver.getCoreSettingsLocked());
6013            updateLruProcessLocked(app, false, null);
6014            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6015        } catch (Exception e) {
6016            // todo: Yikes!  What should we do?  For now we will try to
6017            // start another process, but that could easily get us in
6018            // an infinite loop of restarting processes...
6019            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6020
6021            app.resetPackageList(mProcessStats);
6022            app.unlinkDeathRecipient();
6023            startProcessLocked(app, "bind fail", processName);
6024            return false;
6025        }
6026
6027        // Remove this record from the list of starting applications.
6028        mPersistentStartingProcesses.remove(app);
6029        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6030                "Attach application locked removing on hold: " + app);
6031        mProcessesOnHold.remove(app);
6032
6033        boolean badApp = false;
6034        boolean didSomething = false;
6035
6036        // See if the top visible activity is waiting to run in this process...
6037        if (normalMode) {
6038            try {
6039                if (mStackSupervisor.attachApplicationLocked(app)) {
6040                    didSomething = true;
6041                }
6042            } catch (Exception e) {
6043                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6044                badApp = true;
6045            }
6046        }
6047
6048        // Find any services that should be running in this process...
6049        if (!badApp) {
6050            try {
6051                didSomething |= mServices.attachApplicationLocked(app, processName);
6052            } catch (Exception e) {
6053                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6054                badApp = true;
6055            }
6056        }
6057
6058        // Check if a next-broadcast receiver is in this process...
6059        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6060            try {
6061                didSomething |= sendPendingBroadcastsLocked(app);
6062            } catch (Exception e) {
6063                // If the app died trying to launch the receiver we declare it 'bad'
6064                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6065                badApp = true;
6066            }
6067        }
6068
6069        // Check whether the next backup agent is in this process...
6070        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6071            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6072            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6073            try {
6074                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6075                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6076                        mBackupTarget.backupMode);
6077            } catch (Exception e) {
6078                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6079                badApp = true;
6080            }
6081        }
6082
6083        if (badApp) {
6084            app.kill("error during init", true);
6085            handleAppDiedLocked(app, false, true);
6086            return false;
6087        }
6088
6089        if (!didSomething) {
6090            updateOomAdjLocked();
6091        }
6092
6093        return true;
6094    }
6095
6096    @Override
6097    public final void attachApplication(IApplicationThread thread) {
6098        synchronized (this) {
6099            int callingPid = Binder.getCallingPid();
6100            final long origId = Binder.clearCallingIdentity();
6101            attachApplicationLocked(thread, callingPid);
6102            Binder.restoreCallingIdentity(origId);
6103        }
6104    }
6105
6106    @Override
6107    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6108        final long origId = Binder.clearCallingIdentity();
6109        synchronized (this) {
6110            ActivityStack stack = ActivityRecord.getStackLocked(token);
6111            if (stack != null) {
6112                ActivityRecord r =
6113                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6114                if (stopProfiling) {
6115                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6116                        try {
6117                            mProfileFd.close();
6118                        } catch (IOException e) {
6119                        }
6120                        clearProfilerLocked();
6121                    }
6122                }
6123            }
6124        }
6125        Binder.restoreCallingIdentity(origId);
6126    }
6127
6128    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6129        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6130                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6131    }
6132
6133    void enableScreenAfterBoot() {
6134        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6135                SystemClock.uptimeMillis());
6136        mWindowManager.enableScreenAfterBoot();
6137
6138        synchronized (this) {
6139            updateEventDispatchingLocked();
6140        }
6141    }
6142
6143    @Override
6144    public void showBootMessage(final CharSequence msg, final boolean always) {
6145        enforceNotIsolatedCaller("showBootMessage");
6146        mWindowManager.showBootMessage(msg, always);
6147    }
6148
6149    @Override
6150    public void keyguardWaitingForActivityDrawn() {
6151        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6152        final long token = Binder.clearCallingIdentity();
6153        try {
6154            synchronized (this) {
6155                if (DEBUG_LOCKSCREEN) logLockScreen("");
6156                mWindowManager.keyguardWaitingForActivityDrawn();
6157                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6158                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6159                    updateSleepIfNeededLocked();
6160                }
6161            }
6162        } finally {
6163            Binder.restoreCallingIdentity(token);
6164        }
6165    }
6166
6167    final void finishBooting() {
6168        synchronized (this) {
6169            if (!mBootAnimationComplete) {
6170                mCallFinishBooting = true;
6171                return;
6172            }
6173            mCallFinishBooting = false;
6174        }
6175
6176        ArraySet<String> completedIsas = new ArraySet<String>();
6177        for (String abi : Build.SUPPORTED_ABIS) {
6178            Process.establishZygoteConnectionForAbi(abi);
6179            final String instructionSet = VMRuntime.getInstructionSet(abi);
6180            if (!completedIsas.contains(instructionSet)) {
6181                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6182                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6183                }
6184                completedIsas.add(instructionSet);
6185            }
6186        }
6187
6188        IntentFilter pkgFilter = new IntentFilter();
6189        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6190        pkgFilter.addDataScheme("package");
6191        mContext.registerReceiver(new BroadcastReceiver() {
6192            @Override
6193            public void onReceive(Context context, Intent intent) {
6194                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6195                if (pkgs != null) {
6196                    for (String pkg : pkgs) {
6197                        synchronized (ActivityManagerService.this) {
6198                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6199                                    0, "finished booting")) {
6200                                setResultCode(Activity.RESULT_OK);
6201                                return;
6202                            }
6203                        }
6204                    }
6205                }
6206            }
6207        }, pkgFilter);
6208
6209        // Let system services know.
6210        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6211
6212        synchronized (this) {
6213            // Ensure that any processes we had put on hold are now started
6214            // up.
6215            final int NP = mProcessesOnHold.size();
6216            if (NP > 0) {
6217                ArrayList<ProcessRecord> procs =
6218                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6219                for (int ip=0; ip<NP; ip++) {
6220                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6221                            + procs.get(ip));
6222                    startProcessLocked(procs.get(ip), "on-hold", null);
6223                }
6224            }
6225
6226            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6227                // Start looking for apps that are abusing wake locks.
6228                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6229                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6230                // Tell anyone interested that we are done booting!
6231                SystemProperties.set("sys.boot_completed", "1");
6232
6233                // And trigger dev.bootcomplete if we are not showing encryption progress
6234                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6235                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6236                    SystemProperties.set("dev.bootcomplete", "1");
6237                }
6238                for (int i=0; i<mStartedUsers.size(); i++) {
6239                    UserStartedState uss = mStartedUsers.valueAt(i);
6240                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6241                        uss.mState = UserStartedState.STATE_RUNNING;
6242                        final int userId = mStartedUsers.keyAt(i);
6243                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6244                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6245                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6246                        broadcastIntentLocked(null, null, intent, null,
6247                                new IIntentReceiver.Stub() {
6248                                    @Override
6249                                    public void performReceive(Intent intent, int resultCode,
6250                                            String data, Bundle extras, boolean ordered,
6251                                            boolean sticky, int sendingUser) {
6252                                        synchronized (ActivityManagerService.this) {
6253                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6254                                                    true, false);
6255                                        }
6256                                    }
6257                                },
6258                                0, null, null,
6259                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6260                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6261                                userId);
6262                    }
6263                }
6264                scheduleStartProfilesLocked();
6265            }
6266        }
6267    }
6268
6269    @Override
6270    public void bootAnimationComplete() {
6271        final boolean callFinishBooting;
6272        synchronized (this) {
6273            callFinishBooting = mCallFinishBooting;
6274            mBootAnimationComplete = true;
6275        }
6276        if (callFinishBooting) {
6277            finishBooting();
6278        }
6279    }
6280
6281    @Override
6282    public void systemBackupRestored() {
6283        synchronized (this) {
6284            if (mSystemReady) {
6285                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6286            } else {
6287                Slog.w(TAG, "System backup restored before system is ready");
6288            }
6289        }
6290    }
6291
6292    final void ensureBootCompleted() {
6293        boolean booting;
6294        boolean enableScreen;
6295        synchronized (this) {
6296            booting = mBooting;
6297            mBooting = false;
6298            enableScreen = !mBooted;
6299            mBooted = true;
6300        }
6301
6302        if (booting) {
6303            finishBooting();
6304        }
6305
6306        if (enableScreen) {
6307            enableScreenAfterBoot();
6308        }
6309    }
6310
6311    @Override
6312    public final void activityResumed(IBinder token) {
6313        final long origId = Binder.clearCallingIdentity();
6314        synchronized(this) {
6315            ActivityStack stack = ActivityRecord.getStackLocked(token);
6316            if (stack != null) {
6317                ActivityRecord.activityResumedLocked(token);
6318            }
6319        }
6320        Binder.restoreCallingIdentity(origId);
6321    }
6322
6323    @Override
6324    public final void activityPaused(IBinder token) {
6325        final long origId = Binder.clearCallingIdentity();
6326        synchronized(this) {
6327            ActivityStack stack = ActivityRecord.getStackLocked(token);
6328            if (stack != null) {
6329                stack.activityPausedLocked(token, false);
6330            }
6331        }
6332        Binder.restoreCallingIdentity(origId);
6333    }
6334
6335    @Override
6336    public final void activityStopped(IBinder token, Bundle icicle,
6337            PersistableBundle persistentState, CharSequence description) {
6338        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6339
6340        // Refuse possible leaked file descriptors
6341        if (icicle != null && icicle.hasFileDescriptors()) {
6342            throw new IllegalArgumentException("File descriptors passed in Bundle");
6343        }
6344
6345        final long origId = Binder.clearCallingIdentity();
6346
6347        synchronized (this) {
6348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6349            if (r != null) {
6350                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6351            }
6352        }
6353
6354        trimApplications();
6355
6356        Binder.restoreCallingIdentity(origId);
6357    }
6358
6359    @Override
6360    public final void activityDestroyed(IBinder token) {
6361        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6362        synchronized (this) {
6363            ActivityStack stack = ActivityRecord.getStackLocked(token);
6364            if (stack != null) {
6365                stack.activityDestroyedLocked(token, "activityDestroyed");
6366            }
6367        }
6368    }
6369
6370    @Override
6371    public final void backgroundResourcesReleased(IBinder token) {
6372        final long origId = Binder.clearCallingIdentity();
6373        try {
6374            synchronized (this) {
6375                ActivityStack stack = ActivityRecord.getStackLocked(token);
6376                if (stack != null) {
6377                    stack.backgroundResourcesReleased();
6378                }
6379            }
6380        } finally {
6381            Binder.restoreCallingIdentity(origId);
6382        }
6383    }
6384
6385    @Override
6386    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6387        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6388    }
6389
6390    @Override
6391    public final void notifyEnterAnimationComplete(IBinder token) {
6392        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6393    }
6394
6395    @Override
6396    public String getCallingPackage(IBinder token) {
6397        synchronized (this) {
6398            ActivityRecord r = getCallingRecordLocked(token);
6399            return r != null ? r.info.packageName : null;
6400        }
6401    }
6402
6403    @Override
6404    public ComponentName getCallingActivity(IBinder token) {
6405        synchronized (this) {
6406            ActivityRecord r = getCallingRecordLocked(token);
6407            return r != null ? r.intent.getComponent() : null;
6408        }
6409    }
6410
6411    private ActivityRecord getCallingRecordLocked(IBinder token) {
6412        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6413        if (r == null) {
6414            return null;
6415        }
6416        return r.resultTo;
6417    }
6418
6419    @Override
6420    public ComponentName getActivityClassForToken(IBinder token) {
6421        synchronized(this) {
6422            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6423            if (r == null) {
6424                return null;
6425            }
6426            return r.intent.getComponent();
6427        }
6428    }
6429
6430    @Override
6431    public String getPackageForToken(IBinder token) {
6432        synchronized(this) {
6433            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6434            if (r == null) {
6435                return null;
6436            }
6437            return r.packageName;
6438        }
6439    }
6440
6441    @Override
6442    public IIntentSender getIntentSender(int type,
6443            String packageName, IBinder token, String resultWho,
6444            int requestCode, Intent[] intents, String[] resolvedTypes,
6445            int flags, Bundle options, int userId) {
6446        enforceNotIsolatedCaller("getIntentSender");
6447        // Refuse possible leaked file descriptors
6448        if (intents != null) {
6449            if (intents.length < 1) {
6450                throw new IllegalArgumentException("Intents array length must be >= 1");
6451            }
6452            for (int i=0; i<intents.length; i++) {
6453                Intent intent = intents[i];
6454                if (intent != null) {
6455                    if (intent.hasFileDescriptors()) {
6456                        throw new IllegalArgumentException("File descriptors passed in Intent");
6457                    }
6458                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6459                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6460                        throw new IllegalArgumentException(
6461                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6462                    }
6463                    intents[i] = new Intent(intent);
6464                }
6465            }
6466            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6467                throw new IllegalArgumentException(
6468                        "Intent array length does not match resolvedTypes length");
6469            }
6470        }
6471        if (options != null) {
6472            if (options.hasFileDescriptors()) {
6473                throw new IllegalArgumentException("File descriptors passed in options");
6474            }
6475        }
6476
6477        synchronized(this) {
6478            int callingUid = Binder.getCallingUid();
6479            int origUserId = userId;
6480            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6481                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6482                    ALLOW_NON_FULL, "getIntentSender", null);
6483            if (origUserId == UserHandle.USER_CURRENT) {
6484                // We don't want to evaluate this until the pending intent is
6485                // actually executed.  However, we do want to always do the
6486                // security checking for it above.
6487                userId = UserHandle.USER_CURRENT;
6488            }
6489            try {
6490                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6491                    int uid = AppGlobals.getPackageManager()
6492                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6493                    if (!UserHandle.isSameApp(callingUid, uid)) {
6494                        String msg = "Permission Denial: getIntentSender() from pid="
6495                            + Binder.getCallingPid()
6496                            + ", uid=" + Binder.getCallingUid()
6497                            + ", (need uid=" + uid + ")"
6498                            + " is not allowed to send as package " + packageName;
6499                        Slog.w(TAG, msg);
6500                        throw new SecurityException(msg);
6501                    }
6502                }
6503
6504                return getIntentSenderLocked(type, packageName, callingUid, userId,
6505                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6506
6507            } catch (RemoteException e) {
6508                throw new SecurityException(e);
6509            }
6510        }
6511    }
6512
6513    IIntentSender getIntentSenderLocked(int type, String packageName,
6514            int callingUid, int userId, IBinder token, String resultWho,
6515            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6516            Bundle options) {
6517        if (DEBUG_MU)
6518            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6519        ActivityRecord activity = null;
6520        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6521            activity = ActivityRecord.isInStackLocked(token);
6522            if (activity == null) {
6523                return null;
6524            }
6525            if (activity.finishing) {
6526                return null;
6527            }
6528        }
6529
6530        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6531        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6532        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6533        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6534                |PendingIntent.FLAG_UPDATE_CURRENT);
6535
6536        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6537                type, packageName, activity, resultWho,
6538                requestCode, intents, resolvedTypes, flags, options, userId);
6539        WeakReference<PendingIntentRecord> ref;
6540        ref = mIntentSenderRecords.get(key);
6541        PendingIntentRecord rec = ref != null ? ref.get() : null;
6542        if (rec != null) {
6543            if (!cancelCurrent) {
6544                if (updateCurrent) {
6545                    if (rec.key.requestIntent != null) {
6546                        rec.key.requestIntent.replaceExtras(intents != null ?
6547                                intents[intents.length - 1] : null);
6548                    }
6549                    if (intents != null) {
6550                        intents[intents.length-1] = rec.key.requestIntent;
6551                        rec.key.allIntents = intents;
6552                        rec.key.allResolvedTypes = resolvedTypes;
6553                    } else {
6554                        rec.key.allIntents = null;
6555                        rec.key.allResolvedTypes = null;
6556                    }
6557                }
6558                return rec;
6559            }
6560            rec.canceled = true;
6561            mIntentSenderRecords.remove(key);
6562        }
6563        if (noCreate) {
6564            return rec;
6565        }
6566        rec = new PendingIntentRecord(this, key, callingUid);
6567        mIntentSenderRecords.put(key, rec.ref);
6568        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6569            if (activity.pendingResults == null) {
6570                activity.pendingResults
6571                        = new HashSet<WeakReference<PendingIntentRecord>>();
6572            }
6573            activity.pendingResults.add(rec.ref);
6574        }
6575        return rec;
6576    }
6577
6578    @Override
6579    public void cancelIntentSender(IIntentSender sender) {
6580        if (!(sender instanceof PendingIntentRecord)) {
6581            return;
6582        }
6583        synchronized(this) {
6584            PendingIntentRecord rec = (PendingIntentRecord)sender;
6585            try {
6586                int uid = AppGlobals.getPackageManager()
6587                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6588                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6589                    String msg = "Permission Denial: cancelIntentSender() from pid="
6590                        + Binder.getCallingPid()
6591                        + ", uid=" + Binder.getCallingUid()
6592                        + " is not allowed to cancel packges "
6593                        + rec.key.packageName;
6594                    Slog.w(TAG, msg);
6595                    throw new SecurityException(msg);
6596                }
6597            } catch (RemoteException e) {
6598                throw new SecurityException(e);
6599            }
6600            cancelIntentSenderLocked(rec, true);
6601        }
6602    }
6603
6604    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6605        rec.canceled = true;
6606        mIntentSenderRecords.remove(rec.key);
6607        if (cleanActivity && rec.key.activity != null) {
6608            rec.key.activity.pendingResults.remove(rec.ref);
6609        }
6610    }
6611
6612    @Override
6613    public String getPackageForIntentSender(IIntentSender pendingResult) {
6614        if (!(pendingResult instanceof PendingIntentRecord)) {
6615            return null;
6616        }
6617        try {
6618            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6619            return res.key.packageName;
6620        } catch (ClassCastException e) {
6621        }
6622        return null;
6623    }
6624
6625    @Override
6626    public int getUidForIntentSender(IIntentSender sender) {
6627        if (sender instanceof PendingIntentRecord) {
6628            try {
6629                PendingIntentRecord res = (PendingIntentRecord)sender;
6630                return res.uid;
6631            } catch (ClassCastException e) {
6632            }
6633        }
6634        return -1;
6635    }
6636
6637    @Override
6638    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return false;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            if (res.key.allIntents == null) {
6645                return false;
6646            }
6647            for (int i=0; i<res.key.allIntents.length; i++) {
6648                Intent intent = res.key.allIntents[i];
6649                if (intent.getPackage() != null && intent.getComponent() != null) {
6650                    return false;
6651                }
6652            }
6653            return true;
6654        } catch (ClassCastException e) {
6655        }
6656        return false;
6657    }
6658
6659    @Override
6660    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6661        if (!(pendingResult instanceof PendingIntentRecord)) {
6662            return false;
6663        }
6664        try {
6665            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6666            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6667                return true;
6668            }
6669            return false;
6670        } catch (ClassCastException e) {
6671        }
6672        return false;
6673    }
6674
6675    @Override
6676    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6677        if (!(pendingResult instanceof PendingIntentRecord)) {
6678            return null;
6679        }
6680        try {
6681            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6682            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6683        } catch (ClassCastException e) {
6684        }
6685        return null;
6686    }
6687
6688    @Override
6689    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6690        if (!(pendingResult instanceof PendingIntentRecord)) {
6691            return null;
6692        }
6693        try {
6694            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6695            Intent intent = res.key.requestIntent;
6696            if (intent != null) {
6697                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6698                        || res.lastTagPrefix.equals(prefix))) {
6699                    return res.lastTag;
6700                }
6701                res.lastTagPrefix = prefix;
6702                StringBuilder sb = new StringBuilder(128);
6703                if (prefix != null) {
6704                    sb.append(prefix);
6705                }
6706                if (intent.getAction() != null) {
6707                    sb.append(intent.getAction());
6708                } else if (intent.getComponent() != null) {
6709                    intent.getComponent().appendShortString(sb);
6710                } else {
6711                    sb.append("?");
6712                }
6713                return res.lastTag = sb.toString();
6714            }
6715        } catch (ClassCastException e) {
6716        }
6717        return null;
6718    }
6719
6720    @Override
6721    public void setProcessLimit(int max) {
6722        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6723                "setProcessLimit()");
6724        synchronized (this) {
6725            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6726            mProcessLimitOverride = max;
6727        }
6728        trimApplications();
6729    }
6730
6731    @Override
6732    public int getProcessLimit() {
6733        synchronized (this) {
6734            return mProcessLimitOverride;
6735        }
6736    }
6737
6738    void foregroundTokenDied(ForegroundToken token) {
6739        synchronized (ActivityManagerService.this) {
6740            synchronized (mPidsSelfLocked) {
6741                ForegroundToken cur
6742                    = mForegroundProcesses.get(token.pid);
6743                if (cur != token) {
6744                    return;
6745                }
6746                mForegroundProcesses.remove(token.pid);
6747                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6748                if (pr == null) {
6749                    return;
6750                }
6751                pr.forcingToForeground = null;
6752                updateProcessForegroundLocked(pr, false, false);
6753            }
6754            updateOomAdjLocked();
6755        }
6756    }
6757
6758    @Override
6759    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6760        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6761                "setProcessForeground()");
6762        synchronized(this) {
6763            boolean changed = false;
6764
6765            synchronized (mPidsSelfLocked) {
6766                ProcessRecord pr = mPidsSelfLocked.get(pid);
6767                if (pr == null && isForeground) {
6768                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6769                    return;
6770                }
6771                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6772                if (oldToken != null) {
6773                    oldToken.token.unlinkToDeath(oldToken, 0);
6774                    mForegroundProcesses.remove(pid);
6775                    if (pr != null) {
6776                        pr.forcingToForeground = null;
6777                    }
6778                    changed = true;
6779                }
6780                if (isForeground && token != null) {
6781                    ForegroundToken newToken = new ForegroundToken() {
6782                        @Override
6783                        public void binderDied() {
6784                            foregroundTokenDied(this);
6785                        }
6786                    };
6787                    newToken.pid = pid;
6788                    newToken.token = token;
6789                    try {
6790                        token.linkToDeath(newToken, 0);
6791                        mForegroundProcesses.put(pid, newToken);
6792                        pr.forcingToForeground = token;
6793                        changed = true;
6794                    } catch (RemoteException e) {
6795                        // If the process died while doing this, we will later
6796                        // do the cleanup with the process death link.
6797                    }
6798                }
6799            }
6800
6801            if (changed) {
6802                updateOomAdjLocked();
6803            }
6804        }
6805    }
6806
6807    // =========================================================
6808    // PERMISSIONS
6809    // =========================================================
6810
6811    static class PermissionController extends IPermissionController.Stub {
6812        ActivityManagerService mActivityManagerService;
6813        PermissionController(ActivityManagerService activityManagerService) {
6814            mActivityManagerService = activityManagerService;
6815        }
6816
6817        @Override
6818        public boolean checkPermission(String permission, int pid, int uid) {
6819            return mActivityManagerService.checkPermission(permission, pid,
6820                    uid) == PackageManager.PERMISSION_GRANTED;
6821        }
6822    }
6823
6824    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6825        @Override
6826        public int checkComponentPermission(String permission, int pid, int uid,
6827                int owningUid, boolean exported) {
6828            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6829                    owningUid, exported);
6830        }
6831
6832        @Override
6833        public Object getAMSLock() {
6834            return ActivityManagerService.this;
6835        }
6836    }
6837
6838    /**
6839     * This can be called with or without the global lock held.
6840     */
6841    int checkComponentPermission(String permission, int pid, int uid,
6842            int owningUid, boolean exported) {
6843        if (pid == MY_PID) {
6844            return PackageManager.PERMISSION_GRANTED;
6845        }
6846        return ActivityManager.checkComponentPermission(permission, uid,
6847                owningUid, exported);
6848    }
6849
6850    /**
6851     * As the only public entry point for permissions checking, this method
6852     * can enforce the semantic that requesting a check on a null global
6853     * permission is automatically denied.  (Internally a null permission
6854     * string is used when calling {@link #checkComponentPermission} in cases
6855     * when only uid-based security is needed.)
6856     *
6857     * This can be called with or without the global lock held.
6858     */
6859    @Override
6860    public int checkPermission(String permission, int pid, int uid) {
6861        if (permission == null) {
6862            return PackageManager.PERMISSION_DENIED;
6863        }
6864        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6865    }
6866
6867    @Override
6868    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6869        if (permission == null) {
6870            return PackageManager.PERMISSION_DENIED;
6871        }
6872
6873        // We might be performing an operation on behalf of an indirect binder
6874        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6875        // client identity accordingly before proceeding.
6876        Identity tlsIdentity = sCallerIdentity.get();
6877        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6878            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6879                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6880            uid = tlsIdentity.uid;
6881            pid = tlsIdentity.pid;
6882        }
6883
6884        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6885    }
6886
6887    /**
6888     * Binder IPC calls go through the public entry point.
6889     * This can be called with or without the global lock held.
6890     */
6891    int checkCallingPermission(String permission) {
6892        return checkPermission(permission,
6893                Binder.getCallingPid(),
6894                UserHandle.getAppId(Binder.getCallingUid()));
6895    }
6896
6897    /**
6898     * This can be called with or without the global lock held.
6899     */
6900    void enforceCallingPermission(String permission, String func) {
6901        if (checkCallingPermission(permission)
6902                == PackageManager.PERMISSION_GRANTED) {
6903            return;
6904        }
6905
6906        String msg = "Permission Denial: " + func + " from pid="
6907                + Binder.getCallingPid()
6908                + ", uid=" + Binder.getCallingUid()
6909                + " requires " + permission;
6910        Slog.w(TAG, msg);
6911        throw new SecurityException(msg);
6912    }
6913
6914    /**
6915     * Determine if UID is holding permissions required to access {@link Uri} in
6916     * the given {@link ProviderInfo}. Final permission checking is always done
6917     * in {@link ContentProvider}.
6918     */
6919    private final boolean checkHoldingPermissionsLocked(
6920            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6921        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6922                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6923        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6924            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6925                    != PERMISSION_GRANTED) {
6926                return false;
6927            }
6928        }
6929        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6930    }
6931
6932    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6933            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6934        if (pi.applicationInfo.uid == uid) {
6935            return true;
6936        } else if (!pi.exported) {
6937            return false;
6938        }
6939
6940        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6941        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6942        try {
6943            // check if target holds top-level <provider> permissions
6944            if (!readMet && pi.readPermission != null && considerUidPermissions
6945                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6946                readMet = true;
6947            }
6948            if (!writeMet && pi.writePermission != null && considerUidPermissions
6949                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6950                writeMet = true;
6951            }
6952
6953            // track if unprotected read/write is allowed; any denied
6954            // <path-permission> below removes this ability
6955            boolean allowDefaultRead = pi.readPermission == null;
6956            boolean allowDefaultWrite = pi.writePermission == null;
6957
6958            // check if target holds any <path-permission> that match uri
6959            final PathPermission[] pps = pi.pathPermissions;
6960            if (pps != null) {
6961                final String path = grantUri.uri.getPath();
6962                int i = pps.length;
6963                while (i > 0 && (!readMet || !writeMet)) {
6964                    i--;
6965                    PathPermission pp = pps[i];
6966                    if (pp.match(path)) {
6967                        if (!readMet) {
6968                            final String pprperm = pp.getReadPermission();
6969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6970                                    + pprperm + " for " + pp.getPath()
6971                                    + ": match=" + pp.match(path)
6972                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6973                            if (pprperm != null) {
6974                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6975                                        == PERMISSION_GRANTED) {
6976                                    readMet = true;
6977                                } else {
6978                                    allowDefaultRead = false;
6979                                }
6980                            }
6981                        }
6982                        if (!writeMet) {
6983                            final String ppwperm = pp.getWritePermission();
6984                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6985                                    + ppwperm + " for " + pp.getPath()
6986                                    + ": match=" + pp.match(path)
6987                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6988                            if (ppwperm != null) {
6989                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6990                                        == PERMISSION_GRANTED) {
6991                                    writeMet = true;
6992                                } else {
6993                                    allowDefaultWrite = false;
6994                                }
6995                            }
6996                        }
6997                    }
6998                }
6999            }
7000
7001            // grant unprotected <provider> read/write, if not blocked by
7002            // <path-permission> above
7003            if (allowDefaultRead) readMet = true;
7004            if (allowDefaultWrite) writeMet = true;
7005
7006        } catch (RemoteException e) {
7007            return false;
7008        }
7009
7010        return readMet && writeMet;
7011    }
7012
7013    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7014        ProviderInfo pi = null;
7015        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7016        if (cpr != null) {
7017            pi = cpr.info;
7018        } else {
7019            try {
7020                pi = AppGlobals.getPackageManager().resolveContentProvider(
7021                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7022            } catch (RemoteException ex) {
7023            }
7024        }
7025        return pi;
7026    }
7027
7028    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7029        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7030        if (targetUris != null) {
7031            return targetUris.get(grantUri);
7032        }
7033        return null;
7034    }
7035
7036    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7037            String targetPkg, int targetUid, GrantUri grantUri) {
7038        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7039        if (targetUris == null) {
7040            targetUris = Maps.newArrayMap();
7041            mGrantedUriPermissions.put(targetUid, targetUris);
7042        }
7043
7044        UriPermission perm = targetUris.get(grantUri);
7045        if (perm == null) {
7046            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7047            targetUris.put(grantUri, perm);
7048        }
7049
7050        return perm;
7051    }
7052
7053    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7054            final int modeFlags) {
7055        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7056        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7057                : UriPermission.STRENGTH_OWNED;
7058
7059        // Root gets to do everything.
7060        if (uid == 0) {
7061            return true;
7062        }
7063
7064        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7065        if (perms == null) return false;
7066
7067        // First look for exact match
7068        final UriPermission exactPerm = perms.get(grantUri);
7069        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7070            return true;
7071        }
7072
7073        // No exact match, look for prefixes
7074        final int N = perms.size();
7075        for (int i = 0; i < N; i++) {
7076            final UriPermission perm = perms.valueAt(i);
7077            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7078                    && perm.getStrength(modeFlags) >= minStrength) {
7079                return true;
7080            }
7081        }
7082
7083        return false;
7084    }
7085
7086    /**
7087     * @param uri This uri must NOT contain an embedded userId.
7088     * @param userId The userId in which the uri is to be resolved.
7089     */
7090    @Override
7091    public int checkUriPermission(Uri uri, int pid, int uid,
7092            final int modeFlags, int userId, IBinder callerToken) {
7093        enforceNotIsolatedCaller("checkUriPermission");
7094
7095        // Another redirected-binder-call permissions check as in
7096        // {@link checkPermissionWithToken}.
7097        Identity tlsIdentity = sCallerIdentity.get();
7098        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7099            uid = tlsIdentity.uid;
7100            pid = tlsIdentity.pid;
7101        }
7102
7103        // Our own process gets to do everything.
7104        if (pid == MY_PID) {
7105            return PackageManager.PERMISSION_GRANTED;
7106        }
7107        synchronized (this) {
7108            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7109                    ? PackageManager.PERMISSION_GRANTED
7110                    : PackageManager.PERMISSION_DENIED;
7111        }
7112    }
7113
7114    /**
7115     * Check if the targetPkg can be granted permission to access uri by
7116     * the callingUid using the given modeFlags.  Throws a security exception
7117     * if callingUid is not allowed to do this.  Returns the uid of the target
7118     * if the URI permission grant should be performed; returns -1 if it is not
7119     * needed (for example targetPkg already has permission to access the URI).
7120     * If you already know the uid of the target, you can supply it in
7121     * lastTargetUid else set that to -1.
7122     */
7123    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7124            final int modeFlags, int lastTargetUid) {
7125        if (!Intent.isAccessUriMode(modeFlags)) {
7126            return -1;
7127        }
7128
7129        if (targetPkg != null) {
7130            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7131                    "Checking grant " + targetPkg + " permission to " + grantUri);
7132        }
7133
7134        final IPackageManager pm = AppGlobals.getPackageManager();
7135
7136        // If this is not a content: uri, we can't do anything with it.
7137        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7138            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7139                    "Can't grant URI permission for non-content URI: " + grantUri);
7140            return -1;
7141        }
7142
7143        final String authority = grantUri.uri.getAuthority();
7144        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7145        if (pi == null) {
7146            Slog.w(TAG, "No content provider found for permission check: " +
7147                    grantUri.uri.toSafeString());
7148            return -1;
7149        }
7150
7151        int targetUid = lastTargetUid;
7152        if (targetUid < 0 && targetPkg != null) {
7153            try {
7154                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7155                if (targetUid < 0) {
7156                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7157                            "Can't grant URI permission no uid for: " + targetPkg);
7158                    return -1;
7159                }
7160            } catch (RemoteException ex) {
7161                return -1;
7162            }
7163        }
7164
7165        if (targetUid >= 0) {
7166            // First...  does the target actually need this permission?
7167            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7168                // No need to grant the target this permission.
7169                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7170                        "Target " + targetPkg + " already has full permission to " + grantUri);
7171                return -1;
7172            }
7173        } else {
7174            // First...  there is no target package, so can anyone access it?
7175            boolean allowed = pi.exported;
7176            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7177                if (pi.readPermission != null) {
7178                    allowed = false;
7179                }
7180            }
7181            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7182                if (pi.writePermission != null) {
7183                    allowed = false;
7184                }
7185            }
7186            if (allowed) {
7187                return -1;
7188            }
7189        }
7190
7191        /* There is a special cross user grant if:
7192         * - The target is on another user.
7193         * - Apps on the current user can access the uri without any uid permissions.
7194         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7195         * grant uri permissions.
7196         */
7197        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7198                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7199                modeFlags, false /*without considering the uid permissions*/);
7200
7201        // Second...  is the provider allowing granting of URI permissions?
7202        if (!specialCrossUserGrant) {
7203            if (!pi.grantUriPermissions) {
7204                throw new SecurityException("Provider " + pi.packageName
7205                        + "/" + pi.name
7206                        + " does not allow granting of Uri permissions (uri "
7207                        + grantUri + ")");
7208            }
7209            if (pi.uriPermissionPatterns != null) {
7210                final int N = pi.uriPermissionPatterns.length;
7211                boolean allowed = false;
7212                for (int i=0; i<N; i++) {
7213                    if (pi.uriPermissionPatterns[i] != null
7214                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7215                        allowed = true;
7216                        break;
7217                    }
7218                }
7219                if (!allowed) {
7220                    throw new SecurityException("Provider " + pi.packageName
7221                            + "/" + pi.name
7222                            + " does not allow granting of permission to path of Uri "
7223                            + grantUri);
7224                }
7225            }
7226        }
7227
7228        // Third...  does the caller itself have permission to access
7229        // this uri?
7230        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7231            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7232                // Require they hold a strong enough Uri permission
7233                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7234                    throw new SecurityException("Uid " + callingUid
7235                            + " does not have permission to uri " + grantUri);
7236                }
7237            }
7238        }
7239        return targetUid;
7240    }
7241
7242    /**
7243     * @param uri This uri must NOT contain an embedded userId.
7244     * @param userId The userId in which the uri is to be resolved.
7245     */
7246    @Override
7247    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7248            final int modeFlags, int userId) {
7249        enforceNotIsolatedCaller("checkGrantUriPermission");
7250        synchronized(this) {
7251            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7252                    new GrantUri(userId, uri, false), modeFlags, -1);
7253        }
7254    }
7255
7256    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7257            final int modeFlags, UriPermissionOwner owner) {
7258        if (!Intent.isAccessUriMode(modeFlags)) {
7259            return;
7260        }
7261
7262        // So here we are: the caller has the assumed permission
7263        // to the uri, and the target doesn't.  Let's now give this to
7264        // the target.
7265
7266        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7267                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7268
7269        final String authority = grantUri.uri.getAuthority();
7270        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7271        if (pi == null) {
7272            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7273            return;
7274        }
7275
7276        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7277            grantUri.prefix = true;
7278        }
7279        final UriPermission perm = findOrCreateUriPermissionLocked(
7280                pi.packageName, targetPkg, targetUid, grantUri);
7281        perm.grantModes(modeFlags, owner);
7282    }
7283
7284    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7285            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7286        if (targetPkg == null) {
7287            throw new NullPointerException("targetPkg");
7288        }
7289        int targetUid;
7290        final IPackageManager pm = AppGlobals.getPackageManager();
7291        try {
7292            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7293        } catch (RemoteException ex) {
7294            return;
7295        }
7296
7297        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7298                targetUid);
7299        if (targetUid < 0) {
7300            return;
7301        }
7302
7303        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7304                owner);
7305    }
7306
7307    static class NeededUriGrants extends ArrayList<GrantUri> {
7308        final String targetPkg;
7309        final int targetUid;
7310        final int flags;
7311
7312        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7313            this.targetPkg = targetPkg;
7314            this.targetUid = targetUid;
7315            this.flags = flags;
7316        }
7317    }
7318
7319    /**
7320     * Like checkGrantUriPermissionLocked, but takes an Intent.
7321     */
7322    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7323            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7325                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7326                + " clip=" + (intent != null ? intent.getClipData() : null)
7327                + " from " + intent + "; flags=0x"
7328                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7329
7330        if (targetPkg == null) {
7331            throw new NullPointerException("targetPkg");
7332        }
7333
7334        if (intent == null) {
7335            return null;
7336        }
7337        Uri data = intent.getData();
7338        ClipData clip = intent.getClipData();
7339        if (data == null && clip == null) {
7340            return null;
7341        }
7342        // Default userId for uris in the intent (if they don't specify it themselves)
7343        int contentUserHint = intent.getContentUserHint();
7344        if (contentUserHint == UserHandle.USER_CURRENT) {
7345            contentUserHint = UserHandle.getUserId(callingUid);
7346        }
7347        final IPackageManager pm = AppGlobals.getPackageManager();
7348        int targetUid;
7349        if (needed != null) {
7350            targetUid = needed.targetUid;
7351        } else {
7352            try {
7353                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7354            } catch (RemoteException ex) {
7355                return null;
7356            }
7357            if (targetUid < 0) {
7358                if (DEBUG_URI_PERMISSION) {
7359                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7360                            + " on user " + targetUserId);
7361                }
7362                return null;
7363            }
7364        }
7365        if (data != null) {
7366            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7367            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7368                    targetUid);
7369            if (targetUid > 0) {
7370                if (needed == null) {
7371                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7372                }
7373                needed.add(grantUri);
7374            }
7375        }
7376        if (clip != null) {
7377            for (int i=0; i<clip.getItemCount(); i++) {
7378                Uri uri = clip.getItemAt(i).getUri();
7379                if (uri != null) {
7380                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7381                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7382                            targetUid);
7383                    if (targetUid > 0) {
7384                        if (needed == null) {
7385                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7386                        }
7387                        needed.add(grantUri);
7388                    }
7389                } else {
7390                    Intent clipIntent = clip.getItemAt(i).getIntent();
7391                    if (clipIntent != null) {
7392                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7393                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7394                        if (newNeeded != null) {
7395                            needed = newNeeded;
7396                        }
7397                    }
7398                }
7399            }
7400        }
7401
7402        return needed;
7403    }
7404
7405    /**
7406     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7407     */
7408    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7409            UriPermissionOwner owner) {
7410        if (needed != null) {
7411            for (int i=0; i<needed.size(); i++) {
7412                GrantUri grantUri = needed.get(i);
7413                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7414                        grantUri, needed.flags, owner);
7415            }
7416        }
7417    }
7418
7419    void grantUriPermissionFromIntentLocked(int callingUid,
7420            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7421        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7422                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7423        if (needed == null) {
7424            return;
7425        }
7426
7427        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7428    }
7429
7430    /**
7431     * @param uri This uri must NOT contain an embedded userId.
7432     * @param userId The userId in which the uri is to be resolved.
7433     */
7434    @Override
7435    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7436            final int modeFlags, int userId) {
7437        enforceNotIsolatedCaller("grantUriPermission");
7438        GrantUri grantUri = new GrantUri(userId, uri, false);
7439        synchronized(this) {
7440            final ProcessRecord r = getRecordForAppLocked(caller);
7441            if (r == null) {
7442                throw new SecurityException("Unable to find app for caller "
7443                        + caller
7444                        + " when granting permission to uri " + grantUri);
7445            }
7446            if (targetPkg == null) {
7447                throw new IllegalArgumentException("null target");
7448            }
7449            if (grantUri == null) {
7450                throw new IllegalArgumentException("null uri");
7451            }
7452
7453            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7454                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7455                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7456                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7457
7458            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7459                    UserHandle.getUserId(r.uid));
7460        }
7461    }
7462
7463    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7464        if (perm.modeFlags == 0) {
7465            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7466                    perm.targetUid);
7467            if (perms != null) {
7468                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7469                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7470
7471                perms.remove(perm.uri);
7472                if (perms.isEmpty()) {
7473                    mGrantedUriPermissions.remove(perm.targetUid);
7474                }
7475            }
7476        }
7477    }
7478
7479    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7480        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7481
7482        final IPackageManager pm = AppGlobals.getPackageManager();
7483        final String authority = grantUri.uri.getAuthority();
7484        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7485        if (pi == null) {
7486            Slog.w(TAG, "No content provider found for permission revoke: "
7487                    + grantUri.toSafeString());
7488            return;
7489        }
7490
7491        // Does the caller have this permission on the URI?
7492        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7493            // If they don't have direct access to the URI, then revoke any
7494            // ownerless URI permissions that have been granted to them.
7495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7496            if (perms != null) {
7497                boolean persistChanged = false;
7498                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7499                    final UriPermission perm = it.next();
7500                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7501                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7502                        if (DEBUG_URI_PERMISSION)
7503                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7504                                    " permission to " + perm.uri);
7505                        persistChanged |= perm.revokeModes(
7506                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7507                        if (perm.modeFlags == 0) {
7508                            it.remove();
7509                        }
7510                    }
7511                }
7512                if (perms.isEmpty()) {
7513                    mGrantedUriPermissions.remove(callingUid);
7514                }
7515                if (persistChanged) {
7516                    schedulePersistUriGrants();
7517                }
7518            }
7519            return;
7520        }
7521
7522        boolean persistChanged = false;
7523
7524        // Go through all of the permissions and remove any that match.
7525        int N = mGrantedUriPermissions.size();
7526        for (int i = 0; i < N; i++) {
7527            final int targetUid = mGrantedUriPermissions.keyAt(i);
7528            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7529
7530            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7531                final UriPermission perm = it.next();
7532                if (perm.uri.sourceUserId == grantUri.sourceUserId
7533                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7534                    if (DEBUG_URI_PERMISSION)
7535                        Slog.v(TAG,
7536                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7537                    persistChanged |= perm.revokeModes(
7538                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7539                    if (perm.modeFlags == 0) {
7540                        it.remove();
7541                    }
7542                }
7543            }
7544
7545            if (perms.isEmpty()) {
7546                mGrantedUriPermissions.remove(targetUid);
7547                N--;
7548                i--;
7549            }
7550        }
7551
7552        if (persistChanged) {
7553            schedulePersistUriGrants();
7554        }
7555    }
7556
7557    /**
7558     * @param uri This uri must NOT contain an embedded userId.
7559     * @param userId The userId in which the uri is to be resolved.
7560     */
7561    @Override
7562    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7563            int userId) {
7564        enforceNotIsolatedCaller("revokeUriPermission");
7565        synchronized(this) {
7566            final ProcessRecord r = getRecordForAppLocked(caller);
7567            if (r == null) {
7568                throw new SecurityException("Unable to find app for caller "
7569                        + caller
7570                        + " when revoking permission to uri " + uri);
7571            }
7572            if (uri == null) {
7573                Slog.w(TAG, "revokeUriPermission: null uri");
7574                return;
7575            }
7576
7577            if (!Intent.isAccessUriMode(modeFlags)) {
7578                return;
7579            }
7580
7581            final IPackageManager pm = AppGlobals.getPackageManager();
7582            final String authority = uri.getAuthority();
7583            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7584            if (pi == null) {
7585                Slog.w(TAG, "No content provider found for permission revoke: "
7586                        + uri.toSafeString());
7587                return;
7588            }
7589
7590            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7591        }
7592    }
7593
7594    /**
7595     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7596     * given package.
7597     *
7598     * @param packageName Package name to match, or {@code null} to apply to all
7599     *            packages.
7600     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7601     *            to all users.
7602     * @param persistable If persistable grants should be removed.
7603     */
7604    private void removeUriPermissionsForPackageLocked(
7605            String packageName, int userHandle, boolean persistable) {
7606        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7607            throw new IllegalArgumentException("Must narrow by either package or user");
7608        }
7609
7610        boolean persistChanged = false;
7611
7612        int N = mGrantedUriPermissions.size();
7613        for (int i = 0; i < N; i++) {
7614            final int targetUid = mGrantedUriPermissions.keyAt(i);
7615            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7616
7617            // Only inspect grants matching user
7618            if (userHandle == UserHandle.USER_ALL
7619                    || userHandle == UserHandle.getUserId(targetUid)) {
7620                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7621                    final UriPermission perm = it.next();
7622
7623                    // Only inspect grants matching package
7624                    if (packageName == null || perm.sourcePkg.equals(packageName)
7625                            || perm.targetPkg.equals(packageName)) {
7626                        persistChanged |= perm.revokeModes(persistable
7627                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7628
7629                        // Only remove when no modes remain; any persisted grants
7630                        // will keep this alive.
7631                        if (perm.modeFlags == 0) {
7632                            it.remove();
7633                        }
7634                    }
7635                }
7636
7637                if (perms.isEmpty()) {
7638                    mGrantedUriPermissions.remove(targetUid);
7639                    N--;
7640                    i--;
7641                }
7642            }
7643        }
7644
7645        if (persistChanged) {
7646            schedulePersistUriGrants();
7647        }
7648    }
7649
7650    @Override
7651    public IBinder newUriPermissionOwner(String name) {
7652        enforceNotIsolatedCaller("newUriPermissionOwner");
7653        synchronized(this) {
7654            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7655            return owner.getExternalTokenLocked();
7656        }
7657    }
7658
7659    /**
7660     * @param uri This uri must NOT contain an embedded userId.
7661     * @param sourceUserId The userId in which the uri is to be resolved.
7662     * @param targetUserId The userId of the app that receives the grant.
7663     */
7664    @Override
7665    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7666            final int modeFlags, int sourceUserId, int targetUserId) {
7667        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7668                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7669        synchronized(this) {
7670            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7671            if (owner == null) {
7672                throw new IllegalArgumentException("Unknown owner: " + token);
7673            }
7674            if (fromUid != Binder.getCallingUid()) {
7675                if (Binder.getCallingUid() != Process.myUid()) {
7676                    // Only system code can grant URI permissions on behalf
7677                    // of other users.
7678                    throw new SecurityException("nice try");
7679                }
7680            }
7681            if (targetPkg == null) {
7682                throw new IllegalArgumentException("null target");
7683            }
7684            if (uri == null) {
7685                throw new IllegalArgumentException("null uri");
7686            }
7687
7688            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7689                    modeFlags, owner, targetUserId);
7690        }
7691    }
7692
7693    /**
7694     * @param uri This uri must NOT contain an embedded userId.
7695     * @param userId The userId in which the uri is to be resolved.
7696     */
7697    @Override
7698    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7699        synchronized(this) {
7700            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7701            if (owner == null) {
7702                throw new IllegalArgumentException("Unknown owner: " + token);
7703            }
7704
7705            if (uri == null) {
7706                owner.removeUriPermissionsLocked(mode);
7707            } else {
7708                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7709            }
7710        }
7711    }
7712
7713    private void schedulePersistUriGrants() {
7714        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7715            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7716                    10 * DateUtils.SECOND_IN_MILLIS);
7717        }
7718    }
7719
7720    private void writeGrantedUriPermissions() {
7721        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7722
7723        // Snapshot permissions so we can persist without lock
7724        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7725        synchronized (this) {
7726            final int size = mGrantedUriPermissions.size();
7727            for (int i = 0; i < size; i++) {
7728                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7729                for (UriPermission perm : perms.values()) {
7730                    if (perm.persistedModeFlags != 0) {
7731                        persist.add(perm.snapshot());
7732                    }
7733                }
7734            }
7735        }
7736
7737        FileOutputStream fos = null;
7738        try {
7739            fos = mGrantFile.startWrite();
7740
7741            XmlSerializer out = new FastXmlSerializer();
7742            out.setOutput(fos, "utf-8");
7743            out.startDocument(null, true);
7744            out.startTag(null, TAG_URI_GRANTS);
7745            for (UriPermission.Snapshot perm : persist) {
7746                out.startTag(null, TAG_URI_GRANT);
7747                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7748                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7749                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7750                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7751                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7752                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7753                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7754                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7755                out.endTag(null, TAG_URI_GRANT);
7756            }
7757            out.endTag(null, TAG_URI_GRANTS);
7758            out.endDocument();
7759
7760            mGrantFile.finishWrite(fos);
7761        } catch (IOException e) {
7762            if (fos != null) {
7763                mGrantFile.failWrite(fos);
7764            }
7765        }
7766    }
7767
7768    private void readGrantedUriPermissionsLocked() {
7769        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7770
7771        final long now = System.currentTimeMillis();
7772
7773        FileInputStream fis = null;
7774        try {
7775            fis = mGrantFile.openRead();
7776            final XmlPullParser in = Xml.newPullParser();
7777            in.setInput(fis, null);
7778
7779            int type;
7780            while ((type = in.next()) != END_DOCUMENT) {
7781                final String tag = in.getName();
7782                if (type == START_TAG) {
7783                    if (TAG_URI_GRANT.equals(tag)) {
7784                        final int sourceUserId;
7785                        final int targetUserId;
7786                        final int userHandle = readIntAttribute(in,
7787                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7788                        if (userHandle != UserHandle.USER_NULL) {
7789                            // For backwards compatibility.
7790                            sourceUserId = userHandle;
7791                            targetUserId = userHandle;
7792                        } else {
7793                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7794                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7795                        }
7796                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7797                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7798                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7799                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7800                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7801                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7802
7803                        // Sanity check that provider still belongs to source package
7804                        final ProviderInfo pi = getProviderInfoLocked(
7805                                uri.getAuthority(), sourceUserId);
7806                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7807                            int targetUid = -1;
7808                            try {
7809                                targetUid = AppGlobals.getPackageManager()
7810                                        .getPackageUid(targetPkg, targetUserId);
7811                            } catch (RemoteException e) {
7812                            }
7813                            if (targetUid != -1) {
7814                                final UriPermission perm = findOrCreateUriPermissionLocked(
7815                                        sourcePkg, targetPkg, targetUid,
7816                                        new GrantUri(sourceUserId, uri, prefix));
7817                                perm.initPersistedModes(modeFlags, createdTime);
7818                            }
7819                        } else {
7820                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7821                                    + " but instead found " + pi);
7822                        }
7823                    }
7824                }
7825            }
7826        } catch (FileNotFoundException e) {
7827            // Missing grants is okay
7828        } catch (IOException e) {
7829            Slog.wtf(TAG, "Failed reading Uri grants", e);
7830        } catch (XmlPullParserException e) {
7831            Slog.wtf(TAG, "Failed reading Uri grants", e);
7832        } finally {
7833            IoUtils.closeQuietly(fis);
7834        }
7835    }
7836
7837    /**
7838     * @param uri This uri must NOT contain an embedded userId.
7839     * @param userId The userId in which the uri is to be resolved.
7840     */
7841    @Override
7842    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7843        enforceNotIsolatedCaller("takePersistableUriPermission");
7844
7845        Preconditions.checkFlagsArgument(modeFlags,
7846                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7847
7848        synchronized (this) {
7849            final int callingUid = Binder.getCallingUid();
7850            boolean persistChanged = false;
7851            GrantUri grantUri = new GrantUri(userId, uri, false);
7852
7853            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7854                    new GrantUri(userId, uri, false));
7855            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7856                    new GrantUri(userId, uri, true));
7857
7858            final boolean exactValid = (exactPerm != null)
7859                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7860            final boolean prefixValid = (prefixPerm != null)
7861                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7862
7863            if (!(exactValid || prefixValid)) {
7864                throw new SecurityException("No persistable permission grants found for UID "
7865                        + callingUid + " and Uri " + grantUri.toSafeString());
7866            }
7867
7868            if (exactValid) {
7869                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7870            }
7871            if (prefixValid) {
7872                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7873            }
7874
7875            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7876
7877            if (persistChanged) {
7878                schedulePersistUriGrants();
7879            }
7880        }
7881    }
7882
7883    /**
7884     * @param uri This uri must NOT contain an embedded userId.
7885     * @param userId The userId in which the uri is to be resolved.
7886     */
7887    @Override
7888    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7889        enforceNotIsolatedCaller("releasePersistableUriPermission");
7890
7891        Preconditions.checkFlagsArgument(modeFlags,
7892                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7893
7894        synchronized (this) {
7895            final int callingUid = Binder.getCallingUid();
7896            boolean persistChanged = false;
7897
7898            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7899                    new GrantUri(userId, uri, false));
7900            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7901                    new GrantUri(userId, uri, true));
7902            if (exactPerm == null && prefixPerm == null) {
7903                throw new SecurityException("No permission grants found for UID " + callingUid
7904                        + " and Uri " + uri.toSafeString());
7905            }
7906
7907            if (exactPerm != null) {
7908                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7909                removeUriPermissionIfNeededLocked(exactPerm);
7910            }
7911            if (prefixPerm != null) {
7912                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7913                removeUriPermissionIfNeededLocked(prefixPerm);
7914            }
7915
7916            if (persistChanged) {
7917                schedulePersistUriGrants();
7918            }
7919        }
7920    }
7921
7922    /**
7923     * Prune any older {@link UriPermission} for the given UID until outstanding
7924     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7925     *
7926     * @return if any mutations occured that require persisting.
7927     */
7928    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7929        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7930        if (perms == null) return false;
7931        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7932
7933        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7934        for (UriPermission perm : perms.values()) {
7935            if (perm.persistedModeFlags != 0) {
7936                persisted.add(perm);
7937            }
7938        }
7939
7940        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7941        if (trimCount <= 0) return false;
7942
7943        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7944        for (int i = 0; i < trimCount; i++) {
7945            final UriPermission perm = persisted.get(i);
7946
7947            if (DEBUG_URI_PERMISSION) {
7948                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7949            }
7950
7951            perm.releasePersistableModes(~0);
7952            removeUriPermissionIfNeededLocked(perm);
7953        }
7954
7955        return true;
7956    }
7957
7958    @Override
7959    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7960            String packageName, boolean incoming) {
7961        enforceNotIsolatedCaller("getPersistedUriPermissions");
7962        Preconditions.checkNotNull(packageName, "packageName");
7963
7964        final int callingUid = Binder.getCallingUid();
7965        final IPackageManager pm = AppGlobals.getPackageManager();
7966        try {
7967            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7968            if (packageUid != callingUid) {
7969                throw new SecurityException(
7970                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7971            }
7972        } catch (RemoteException e) {
7973            throw new SecurityException("Failed to verify package name ownership");
7974        }
7975
7976        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7977        synchronized (this) {
7978            if (incoming) {
7979                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7980                        callingUid);
7981                if (perms == null) {
7982                    Slog.w(TAG, "No permission grants found for " + packageName);
7983                } else {
7984                    for (UriPermission perm : perms.values()) {
7985                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7986                            result.add(perm.buildPersistedPublicApiObject());
7987                        }
7988                    }
7989                }
7990            } else {
7991                final int size = mGrantedUriPermissions.size();
7992                for (int i = 0; i < size; i++) {
7993                    final ArrayMap<GrantUri, UriPermission> perms =
7994                            mGrantedUriPermissions.valueAt(i);
7995                    for (UriPermission perm : perms.values()) {
7996                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7997                            result.add(perm.buildPersistedPublicApiObject());
7998                        }
7999                    }
8000                }
8001            }
8002        }
8003        return new ParceledListSlice<android.content.UriPermission>(result);
8004    }
8005
8006    @Override
8007    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8008        synchronized (this) {
8009            ProcessRecord app =
8010                who != null ? getRecordForAppLocked(who) : null;
8011            if (app == null) return;
8012
8013            Message msg = Message.obtain();
8014            msg.what = WAIT_FOR_DEBUGGER_MSG;
8015            msg.obj = app;
8016            msg.arg1 = waiting ? 1 : 0;
8017            mHandler.sendMessage(msg);
8018        }
8019    }
8020
8021    @Override
8022    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8023        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8024        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8025        outInfo.availMem = Process.getFreeMemory();
8026        outInfo.totalMem = Process.getTotalMemory();
8027        outInfo.threshold = homeAppMem;
8028        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8029        outInfo.hiddenAppThreshold = cachedAppMem;
8030        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8031                ProcessList.SERVICE_ADJ);
8032        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8033                ProcessList.VISIBLE_APP_ADJ);
8034        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8035                ProcessList.FOREGROUND_APP_ADJ);
8036    }
8037
8038    // =========================================================
8039    // TASK MANAGEMENT
8040    // =========================================================
8041
8042    @Override
8043    public List<IAppTask> getAppTasks(String callingPackage) {
8044        int callingUid = Binder.getCallingUid();
8045        long ident = Binder.clearCallingIdentity();
8046
8047        synchronized(this) {
8048            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8049            try {
8050                if (localLOGV) Slog.v(TAG, "getAppTasks");
8051
8052                final int N = mRecentTasks.size();
8053                for (int i = 0; i < N; i++) {
8054                    TaskRecord tr = mRecentTasks.get(i);
8055                    // Skip tasks that do not match the caller.  We don't need to verify
8056                    // callingPackage, because we are also limiting to callingUid and know
8057                    // that will limit to the correct security sandbox.
8058                    if (tr.effectiveUid != callingUid) {
8059                        continue;
8060                    }
8061                    Intent intent = tr.getBaseIntent();
8062                    if (intent == null ||
8063                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8064                        continue;
8065                    }
8066                    ActivityManager.RecentTaskInfo taskInfo =
8067                            createRecentTaskInfoFromTaskRecord(tr);
8068                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8069                    list.add(taskImpl);
8070                }
8071            } finally {
8072                Binder.restoreCallingIdentity(ident);
8073            }
8074            return list;
8075        }
8076    }
8077
8078    @Override
8079    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8080        final int callingUid = Binder.getCallingUid();
8081        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8082
8083        synchronized(this) {
8084            if (localLOGV) Slog.v(
8085                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8086
8087            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8088                    callingUid);
8089
8090            // TODO: Improve with MRU list from all ActivityStacks.
8091            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8092        }
8093
8094        return list;
8095    }
8096
8097    /**
8098     * Creates a new RecentTaskInfo from a TaskRecord.
8099     */
8100    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8101        // Update the task description to reflect any changes in the task stack
8102        tr.updateTaskDescription();
8103
8104        // Compose the recent task info
8105        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8106        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8107        rti.persistentId = tr.taskId;
8108        rti.baseIntent = new Intent(tr.getBaseIntent());
8109        rti.origActivity = tr.origActivity;
8110        rti.description = tr.lastDescription;
8111        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8112        rti.userId = tr.userId;
8113        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8114        rti.firstActiveTime = tr.firstActiveTime;
8115        rti.lastActiveTime = tr.lastActiveTime;
8116        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8117        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8118        return rti;
8119    }
8120
8121    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8122        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8123                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8124        if (!allowed) {
8125            if (checkPermission(android.Manifest.permission.GET_TASKS,
8126                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8127                // Temporary compatibility: some existing apps on the system image may
8128                // still be requesting the old permission and not switched to the new
8129                // one; if so, we'll still allow them full access.  This means we need
8130                // to see if they are holding the old permission and are a system app.
8131                try {
8132                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8133                        allowed = true;
8134                        Slog.w(TAG, caller + ": caller " + callingUid
8135                                + " is using old GET_TASKS but privileged; allowing");
8136                    }
8137                } catch (RemoteException e) {
8138                }
8139            }
8140        }
8141        if (!allowed) {
8142            Slog.w(TAG, caller + ": caller " + callingUid
8143                    + " does not hold GET_TASKS; limiting output");
8144        }
8145        return allowed;
8146    }
8147
8148    @Override
8149    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8150        final int callingUid = Binder.getCallingUid();
8151        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8152                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8153
8154        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8155        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8156        synchronized (this) {
8157            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8158                    callingUid);
8159            final boolean detailed = checkCallingPermission(
8160                    android.Manifest.permission.GET_DETAILED_TASKS)
8161                    == PackageManager.PERMISSION_GRANTED;
8162
8163            final int N = mRecentTasks.size();
8164            ArrayList<ActivityManager.RecentTaskInfo> res
8165                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8166                            maxNum < N ? maxNum : N);
8167
8168            final Set<Integer> includedUsers;
8169            if (includeProfiles) {
8170                includedUsers = getProfileIdsLocked(userId);
8171            } else {
8172                includedUsers = new HashSet<Integer>();
8173            }
8174            includedUsers.add(Integer.valueOf(userId));
8175
8176            for (int i=0; i<N && maxNum > 0; i++) {
8177                TaskRecord tr = mRecentTasks.get(i);
8178                // Only add calling user or related users recent tasks
8179                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8180                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8181                    continue;
8182                }
8183
8184                // Return the entry if desired by the caller.  We always return
8185                // the first entry, because callers always expect this to be the
8186                // foreground app.  We may filter others if the caller has
8187                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8188                // we should exclude the entry.
8189
8190                if (i == 0
8191                        || withExcluded
8192                        || (tr.intent == null)
8193                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8194                                == 0)) {
8195                    if (!allowed) {
8196                        // If the caller doesn't have the GET_TASKS permission, then only
8197                        // allow them to see a small subset of tasks -- their own and home.
8198                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8199                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8200                            continue;
8201                        }
8202                    }
8203                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8204                        if (tr.stack != null && tr.stack.isHomeStack()) {
8205                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8206                            continue;
8207                        }
8208                    }
8209                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8210                        // Don't include auto remove tasks that are finished or finishing.
8211                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8212                                + tr);
8213                        continue;
8214                    }
8215                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8216                            && !tr.isAvailable) {
8217                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8218                        continue;
8219                    }
8220
8221                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8222                    if (!detailed) {
8223                        rti.baseIntent.replaceExtras((Bundle)null);
8224                    }
8225
8226                    res.add(rti);
8227                    maxNum--;
8228                }
8229            }
8230            return res;
8231        }
8232    }
8233
8234    TaskRecord recentTaskForIdLocked(int id) {
8235        final int N = mRecentTasks.size();
8236            for (int i=0; i<N; i++) {
8237                TaskRecord tr = mRecentTasks.get(i);
8238                if (tr.taskId == id) {
8239                    return tr;
8240                }
8241            }
8242            return null;
8243    }
8244
8245    @Override
8246    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8247        synchronized (this) {
8248            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8249                    "getTaskThumbnail()");
8250            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8251            if (tr != null) {
8252                return tr.getTaskThumbnailLocked();
8253            }
8254        }
8255        return null;
8256    }
8257
8258    @Override
8259    public int addAppTask(IBinder activityToken, Intent intent,
8260            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8261        final int callingUid = Binder.getCallingUid();
8262        final long callingIdent = Binder.clearCallingIdentity();
8263
8264        try {
8265            synchronized (this) {
8266                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8267                if (r == null) {
8268                    throw new IllegalArgumentException("Activity does not exist; token="
8269                            + activityToken);
8270                }
8271                ComponentName comp = intent.getComponent();
8272                if (comp == null) {
8273                    throw new IllegalArgumentException("Intent " + intent
8274                            + " must specify explicit component");
8275                }
8276                if (thumbnail.getWidth() != mThumbnailWidth
8277                        || thumbnail.getHeight() != mThumbnailHeight) {
8278                    throw new IllegalArgumentException("Bad thumbnail size: got "
8279                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8280                            + mThumbnailWidth + "x" + mThumbnailHeight);
8281                }
8282                if (intent.getSelector() != null) {
8283                    intent.setSelector(null);
8284                }
8285                if (intent.getSourceBounds() != null) {
8286                    intent.setSourceBounds(null);
8287                }
8288                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8289                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8290                        // The caller has added this as an auto-remove task...  that makes no
8291                        // sense, so turn off auto-remove.
8292                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8293                    }
8294                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8295                    // Must be a new task.
8296                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8297                }
8298                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8299                    mLastAddedTaskActivity = null;
8300                }
8301                ActivityInfo ainfo = mLastAddedTaskActivity;
8302                if (ainfo == null) {
8303                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8304                            comp, 0, UserHandle.getUserId(callingUid));
8305                    if (ainfo.applicationInfo.uid != callingUid) {
8306                        throw new SecurityException(
8307                                "Can't add task for another application: target uid="
8308                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8309                    }
8310                }
8311
8312                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8313                        intent, description);
8314
8315                int trimIdx = trimRecentsForTaskLocked(task, false);
8316                if (trimIdx >= 0) {
8317                    // If this would have caused a trim, then we'll abort because that
8318                    // means it would be added at the end of the list but then just removed.
8319                    return INVALID_TASK_ID;
8320                }
8321
8322                final int N = mRecentTasks.size();
8323                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8324                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8325                    tr.removedFromRecents();
8326                }
8327
8328                task.inRecents = true;
8329                mRecentTasks.add(task);
8330                r.task.stack.addTask(task, false, false);
8331
8332                task.setLastThumbnail(thumbnail);
8333                task.freeLastThumbnail();
8334
8335                return task.taskId;
8336            }
8337        } finally {
8338            Binder.restoreCallingIdentity(callingIdent);
8339        }
8340    }
8341
8342    @Override
8343    public Point getAppTaskThumbnailSize() {
8344        synchronized (this) {
8345            return new Point(mThumbnailWidth,  mThumbnailHeight);
8346        }
8347    }
8348
8349    @Override
8350    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8351        synchronized (this) {
8352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8353            if (r != null) {
8354                r.setTaskDescription(td);
8355                r.task.updateTaskDescription();
8356            }
8357        }
8358    }
8359
8360    @Override
8361    public Bitmap getTaskDescriptionIcon(String filename) {
8362        if (!FileUtils.isValidExtFilename(filename)
8363                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8364            throw new IllegalArgumentException("Bad filename: " + filename);
8365        }
8366        return mTaskPersister.getTaskDescriptionIcon(filename);
8367    }
8368
8369    @Override
8370    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8371            throws RemoteException {
8372        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8373                opts.getCustomInPlaceResId() == 0) {
8374            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8375                    "with valid animation");
8376        }
8377        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8378        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8379                opts.getCustomInPlaceResId());
8380        mWindowManager.executeAppTransition();
8381    }
8382
8383    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8384        mRecentTasks.remove(tr);
8385        tr.removedFromRecents();
8386        ComponentName component = tr.getBaseIntent().getComponent();
8387        if (component == null) {
8388            Slog.w(TAG, "No component for base intent of task: " + tr);
8389            return;
8390        }
8391
8392        if (!killProcess) {
8393            return;
8394        }
8395
8396        // Determine if the process(es) for this task should be killed.
8397        final String pkg = component.getPackageName();
8398        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8399        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8400        for (int i = 0; i < pmap.size(); i++) {
8401
8402            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8403            for (int j = 0; j < uids.size(); j++) {
8404                ProcessRecord proc = uids.valueAt(j);
8405                if (proc.userId != tr.userId) {
8406                    // Don't kill process for a different user.
8407                    continue;
8408                }
8409                if (proc == mHomeProcess) {
8410                    // Don't kill the home process along with tasks from the same package.
8411                    continue;
8412                }
8413                if (!proc.pkgList.containsKey(pkg)) {
8414                    // Don't kill process that is not associated with this task.
8415                    continue;
8416                }
8417
8418                for (int k = 0; k < proc.activities.size(); k++) {
8419                    TaskRecord otherTask = proc.activities.get(k).task;
8420                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8421                        // Don't kill process(es) that has an activity in a different task that is
8422                        // also in recents.
8423                        return;
8424                    }
8425                }
8426
8427                // Add process to kill list.
8428                procsToKill.add(proc);
8429            }
8430        }
8431
8432        // Find any running services associated with this app and stop if needed.
8433        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8434
8435        // Kill the running processes.
8436        for (int i = 0; i < procsToKill.size(); i++) {
8437            ProcessRecord pr = procsToKill.get(i);
8438            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8439                pr.kill("remove task", true);
8440            } else {
8441                pr.waitingToKill = "remove task";
8442            }
8443        }
8444    }
8445
8446    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8447        // Remove all tasks with activities in the specified package from the list of recent tasks
8448        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8449            TaskRecord tr = mRecentTasks.get(i);
8450            if (tr.userId != userId) continue;
8451
8452            ComponentName cn = tr.intent.getComponent();
8453            if (cn != null && cn.getPackageName().equals(packageName)) {
8454                // If the package name matches, remove the task.
8455                removeTaskByIdLocked(tr.taskId, true);
8456            }
8457        }
8458    }
8459
8460    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8461        final IPackageManager pm = AppGlobals.getPackageManager();
8462        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8463
8464        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8465            TaskRecord tr = mRecentTasks.get(i);
8466            if (tr.userId != userId) continue;
8467
8468            ComponentName cn = tr.intent.getComponent();
8469            if (cn != null && cn.getPackageName().equals(packageName)) {
8470                // Skip if component still exists in the package.
8471                if (componentsKnownToExist.contains(cn)) continue;
8472
8473                try {
8474                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8475                    if (info != null) {
8476                        componentsKnownToExist.add(cn);
8477                    } else {
8478                        removeTaskByIdLocked(tr.taskId, false);
8479                    }
8480                } catch (RemoteException e) {
8481                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8482                }
8483            }
8484        }
8485    }
8486
8487    /**
8488     * Removes the task with the specified task id.
8489     *
8490     * @param taskId Identifier of the task to be removed.
8491     * @param killProcess Kill any process associated with the task if possible.
8492     * @return Returns true if the given task was found and removed.
8493     */
8494    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8495        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8496        if (tr != null) {
8497            tr.removeTaskActivitiesLocked();
8498            cleanUpRemovedTaskLocked(tr, killProcess);
8499            if (tr.isPersistable) {
8500                notifyTaskPersisterLocked(null, true);
8501            }
8502            return true;
8503        }
8504        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8505        return false;
8506    }
8507
8508    @Override
8509    public boolean removeTask(int taskId) {
8510        synchronized (this) {
8511            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8512                    "removeTask()");
8513            long ident = Binder.clearCallingIdentity();
8514            try {
8515                return removeTaskByIdLocked(taskId, true);
8516            } finally {
8517                Binder.restoreCallingIdentity(ident);
8518            }
8519        }
8520    }
8521
8522    /**
8523     * TODO: Add mController hook
8524     */
8525    @Override
8526    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8527        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8528                "moveTaskToFront()");
8529
8530        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8531        synchronized(this) {
8532            moveTaskToFrontLocked(taskId, flags, options);
8533        }
8534    }
8535
8536    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8537        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8538                Binder.getCallingUid(), -1, -1, "Task to front")) {
8539            ActivityOptions.abort(options);
8540            return;
8541        }
8542        final long origId = Binder.clearCallingIdentity();
8543        try {
8544            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8545            if (task == null) {
8546                Slog.d(TAG, "Could not find task for id: "+ taskId);
8547                return;
8548            }
8549            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8550                mStackSupervisor.showLockTaskToast();
8551                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8552                return;
8553            }
8554            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8555            if (prev != null && prev.isRecentsActivity()) {
8556                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8557            }
8558            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8559        } finally {
8560            Binder.restoreCallingIdentity(origId);
8561        }
8562        ActivityOptions.abort(options);
8563    }
8564
8565    @Override
8566    public void moveTaskToBack(int taskId) {
8567        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8568                "moveTaskToBack()");
8569
8570        synchronized(this) {
8571            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8572            if (tr != null) {
8573                if (tr == mStackSupervisor.mLockTaskModeTask) {
8574                    mStackSupervisor.showLockTaskToast();
8575                    return;
8576                }
8577                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8578                ActivityStack stack = tr.stack;
8579                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8580                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8581                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8582                        return;
8583                    }
8584                }
8585                final long origId = Binder.clearCallingIdentity();
8586                try {
8587                    stack.moveTaskToBackLocked(taskId);
8588                } finally {
8589                    Binder.restoreCallingIdentity(origId);
8590                }
8591            }
8592        }
8593    }
8594
8595    /**
8596     * Moves an activity, and all of the other activities within the same task, to the bottom
8597     * of the history stack.  The activity's order within the task is unchanged.
8598     *
8599     * @param token A reference to the activity we wish to move
8600     * @param nonRoot If false then this only works if the activity is the root
8601     *                of a task; if true it will work for any activity in a task.
8602     * @return Returns true if the move completed, false if not.
8603     */
8604    @Override
8605    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8606        enforceNotIsolatedCaller("moveActivityTaskToBack");
8607        synchronized(this) {
8608            final long origId = Binder.clearCallingIdentity();
8609            try {
8610                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8611                if (taskId >= 0) {
8612                    if ((mStackSupervisor.mLockTaskModeTask != null)
8613                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8614                        mStackSupervisor.showLockTaskToast();
8615                        return false;
8616                    }
8617                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8618                }
8619            } finally {
8620                Binder.restoreCallingIdentity(origId);
8621            }
8622        }
8623        return false;
8624    }
8625
8626    @Override
8627    public void moveTaskBackwards(int task) {
8628        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8629                "moveTaskBackwards()");
8630
8631        synchronized(this) {
8632            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8633                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8634                return;
8635            }
8636            final long origId = Binder.clearCallingIdentity();
8637            moveTaskBackwardsLocked(task);
8638            Binder.restoreCallingIdentity(origId);
8639        }
8640    }
8641
8642    private final void moveTaskBackwardsLocked(int task) {
8643        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8644    }
8645
8646    @Override
8647    public IBinder getHomeActivityToken() throws RemoteException {
8648        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8649                "getHomeActivityToken()");
8650        synchronized (this) {
8651            return mStackSupervisor.getHomeActivityToken();
8652        }
8653    }
8654
8655    @Override
8656    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8657            IActivityContainerCallback callback) throws RemoteException {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "createActivityContainer()");
8660        synchronized (this) {
8661            if (parentActivityToken == null) {
8662                throw new IllegalArgumentException("parent token must not be null");
8663            }
8664            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8665            if (r == null) {
8666                return null;
8667            }
8668            if (callback == null) {
8669                throw new IllegalArgumentException("callback must not be null");
8670            }
8671            return mStackSupervisor.createActivityContainer(r, callback);
8672        }
8673    }
8674
8675    @Override
8676    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "deleteActivityContainer()");
8679        synchronized (this) {
8680            mStackSupervisor.deleteActivityContainer(container);
8681        }
8682    }
8683
8684    @Override
8685    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8686        synchronized (this) {
8687            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8688            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8689                return stack.mActivityContainer.getDisplayId();
8690            }
8691            return Display.DEFAULT_DISPLAY;
8692        }
8693    }
8694
8695    @Override
8696    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8698                "moveTaskToStack()");
8699        if (stackId == HOME_STACK_ID) {
8700            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8701                    new RuntimeException("here").fillInStackTrace());
8702        }
8703        synchronized (this) {
8704            long ident = Binder.clearCallingIdentity();
8705            try {
8706                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8707                        + stackId + " toTop=" + toTop);
8708                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8709            } finally {
8710                Binder.restoreCallingIdentity(ident);
8711            }
8712        }
8713    }
8714
8715    @Override
8716    public void resizeStack(int stackBoxId, Rect bounds) {
8717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8718                "resizeStackBox()");
8719        long ident = Binder.clearCallingIdentity();
8720        try {
8721            mWindowManager.resizeStack(stackBoxId, bounds);
8722        } finally {
8723            Binder.restoreCallingIdentity(ident);
8724        }
8725    }
8726
8727    @Override
8728    public List<StackInfo> getAllStackInfos() {
8729        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8730                "getAllStackInfos()");
8731        long ident = Binder.clearCallingIdentity();
8732        try {
8733            synchronized (this) {
8734                return mStackSupervisor.getAllStackInfosLocked();
8735            }
8736        } finally {
8737            Binder.restoreCallingIdentity(ident);
8738        }
8739    }
8740
8741    @Override
8742    public StackInfo getStackInfo(int stackId) {
8743        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                "getStackInfo()");
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            synchronized (this) {
8748                return mStackSupervisor.getStackInfoLocked(stackId);
8749            }
8750        } finally {
8751            Binder.restoreCallingIdentity(ident);
8752        }
8753    }
8754
8755    @Override
8756    public boolean isInHomeStack(int taskId) {
8757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8758                "getStackInfo()");
8759        long ident = Binder.clearCallingIdentity();
8760        try {
8761            synchronized (this) {
8762                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8763                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8764            }
8765        } finally {
8766            Binder.restoreCallingIdentity(ident);
8767        }
8768    }
8769
8770    @Override
8771    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8772        synchronized(this) {
8773            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8774        }
8775    }
8776
8777    private boolean isLockTaskAuthorized(String pkg) {
8778        final DevicePolicyManager dpm = (DevicePolicyManager)
8779                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8780        try {
8781            int uid = mContext.getPackageManager().getPackageUid(pkg,
8782                    Binder.getCallingUserHandle().getIdentifier());
8783            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8784        } catch (NameNotFoundException e) {
8785            return false;
8786        }
8787    }
8788
8789    void startLockTaskMode(TaskRecord task) {
8790        final String pkg;
8791        synchronized (this) {
8792            pkg = task.intent.getComponent().getPackageName();
8793        }
8794        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8795        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8796            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8797                    StatusBarManagerInternal.class);
8798            if (statusBarManager != null) {
8799                statusBarManager.showScreenPinningRequest();
8800            }
8801            return;
8802        }
8803        long ident = Binder.clearCallingIdentity();
8804        try {
8805            synchronized (this) {
8806                // Since we lost lock on task, make sure it is still there.
8807                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8808                if (task != null) {
8809                    if (!isSystemInitiated
8810                            && ((mStackSupervisor.getFocusedStack() == null)
8811                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8812                        throw new IllegalArgumentException("Invalid task, not in foreground");
8813                    }
8814                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8815                            "startLockTask");
8816                }
8817            }
8818        } finally {
8819            Binder.restoreCallingIdentity(ident);
8820        }
8821    }
8822
8823    @Override
8824    public void startLockTaskMode(int taskId) {
8825        final TaskRecord task;
8826        long ident = Binder.clearCallingIdentity();
8827        try {
8828            synchronized (this) {
8829                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8830            }
8831        } finally {
8832            Binder.restoreCallingIdentity(ident);
8833        }
8834        if (task != null) {
8835            startLockTaskMode(task);
8836        }
8837    }
8838
8839    @Override
8840    public void startLockTaskMode(IBinder token) {
8841        final TaskRecord task;
8842        long ident = Binder.clearCallingIdentity();
8843        try {
8844            synchronized (this) {
8845                final ActivityRecord r = ActivityRecord.forToken(token);
8846                if (r == null) {
8847                    return;
8848                }
8849                task = r.task;
8850            }
8851        } finally {
8852            Binder.restoreCallingIdentity(ident);
8853        }
8854        if (task != null) {
8855            startLockTaskMode(task);
8856        }
8857    }
8858
8859    @Override
8860    public void startLockTaskModeOnCurrent() throws RemoteException {
8861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8862                "startLockTaskModeOnCurrent");
8863        long ident = Binder.clearCallingIdentity();
8864        try {
8865            ActivityRecord r = null;
8866            synchronized (this) {
8867                r = mStackSupervisor.topRunningActivityLocked();
8868            }
8869            startLockTaskMode(r.task);
8870        } finally {
8871            Binder.restoreCallingIdentity(ident);
8872        }
8873    }
8874
8875    @Override
8876    public void stopLockTaskMode() {
8877        // Verify that the user matches the package of the intent for the TaskRecord
8878        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8879        // and stopLockTaskMode.
8880        final int callingUid = Binder.getCallingUid();
8881        if (callingUid != Process.SYSTEM_UID) {
8882            try {
8883                String pkg =
8884                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8885                int uid = mContext.getPackageManager().getPackageUid(pkg,
8886                        Binder.getCallingUserHandle().getIdentifier());
8887                if (uid != callingUid) {
8888                    throw new SecurityException("Invalid uid, expected " + uid);
8889                }
8890            } catch (NameNotFoundException e) {
8891                Log.d(TAG, "stopLockTaskMode " + e);
8892                return;
8893            }
8894        }
8895        long ident = Binder.clearCallingIdentity();
8896        try {
8897            Log.d(TAG, "stopLockTaskMode");
8898            // Stop lock task
8899            synchronized (this) {
8900                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8901            }
8902        } finally {
8903            Binder.restoreCallingIdentity(ident);
8904        }
8905    }
8906
8907    @Override
8908    public void stopLockTaskModeOnCurrent() throws RemoteException {
8909        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8910                "stopLockTaskModeOnCurrent");
8911        long ident = Binder.clearCallingIdentity();
8912        try {
8913            stopLockTaskMode();
8914        } finally {
8915            Binder.restoreCallingIdentity(ident);
8916        }
8917    }
8918
8919    @Override
8920    public boolean isInLockTaskMode() {
8921        synchronized (this) {
8922            return mStackSupervisor.isInLockTaskMode();
8923        }
8924    }
8925
8926    // =========================================================
8927    // CONTENT PROVIDERS
8928    // =========================================================
8929
8930    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8931        List<ProviderInfo> providers = null;
8932        try {
8933            providers = AppGlobals.getPackageManager().
8934                queryContentProviders(app.processName, app.uid,
8935                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8936        } catch (RemoteException ex) {
8937        }
8938        if (DEBUG_MU)
8939            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8940        int userId = app.userId;
8941        if (providers != null) {
8942            int N = providers.size();
8943            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8944            for (int i=0; i<N; i++) {
8945                ProviderInfo cpi =
8946                    (ProviderInfo)providers.get(i);
8947                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8948                        cpi.name, cpi.flags);
8949                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8950                    // This is a singleton provider, but a user besides the
8951                    // default user is asking to initialize a process it runs
8952                    // in...  well, no, it doesn't actually run in this process,
8953                    // it runs in the process of the default user.  Get rid of it.
8954                    providers.remove(i);
8955                    N--;
8956                    i--;
8957                    continue;
8958                }
8959
8960                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8961                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8962                if (cpr == null) {
8963                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8964                    mProviderMap.putProviderByClass(comp, cpr);
8965                }
8966                if (DEBUG_MU)
8967                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8968                app.pubProviders.put(cpi.name, cpr);
8969                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8970                    // Don't add this if it is a platform component that is marked
8971                    // to run in multiple processes, because this is actually
8972                    // part of the framework so doesn't make sense to track as a
8973                    // separate apk in the process.
8974                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8975                            mProcessStats);
8976                }
8977                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8978            }
8979        }
8980        return providers;
8981    }
8982
8983    /**
8984     * Check if {@link ProcessRecord} has a possible chance at accessing the
8985     * given {@link ProviderInfo}. Final permission checking is always done
8986     * in {@link ContentProvider}.
8987     */
8988    private final String checkContentProviderPermissionLocked(
8989            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8990        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8991        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8992        boolean checkedGrants = false;
8993        if (checkUser) {
8994            // Looking for cross-user grants before enforcing the typical cross-users permissions
8995            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8996            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8997                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8998                    return null;
8999                }
9000                checkedGrants = true;
9001            }
9002            userId = handleIncomingUser(callingPid, callingUid, userId,
9003                    false, ALLOW_NON_FULL,
9004                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9005            if (userId != tmpTargetUserId) {
9006                // When we actually went to determine the final targer user ID, this ended
9007                // up different than our initial check for the authority.  This is because
9008                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9009                // SELF.  So we need to re-check the grants again.
9010                checkedGrants = false;
9011            }
9012        }
9013        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9014                cpi.applicationInfo.uid, cpi.exported)
9015                == PackageManager.PERMISSION_GRANTED) {
9016            return null;
9017        }
9018        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9019                cpi.applicationInfo.uid, cpi.exported)
9020                == PackageManager.PERMISSION_GRANTED) {
9021            return null;
9022        }
9023
9024        PathPermission[] pps = cpi.pathPermissions;
9025        if (pps != null) {
9026            int i = pps.length;
9027            while (i > 0) {
9028                i--;
9029                PathPermission pp = pps[i];
9030                String pprperm = pp.getReadPermission();
9031                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9032                        cpi.applicationInfo.uid, cpi.exported)
9033                        == PackageManager.PERMISSION_GRANTED) {
9034                    return null;
9035                }
9036                String ppwperm = pp.getWritePermission();
9037                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9038                        cpi.applicationInfo.uid, cpi.exported)
9039                        == PackageManager.PERMISSION_GRANTED) {
9040                    return null;
9041                }
9042            }
9043        }
9044        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9045            return null;
9046        }
9047
9048        String msg;
9049        if (!cpi.exported) {
9050            msg = "Permission Denial: opening provider " + cpi.name
9051                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9052                    + ", uid=" + callingUid + ") that is not exported from uid "
9053                    + cpi.applicationInfo.uid;
9054        } else {
9055            msg = "Permission Denial: opening provider " + cpi.name
9056                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9057                    + ", uid=" + callingUid + ") requires "
9058                    + cpi.readPermission + " or " + cpi.writePermission;
9059        }
9060        Slog.w(TAG, msg);
9061        return msg;
9062    }
9063
9064    /**
9065     * Returns if the ContentProvider has granted a uri to callingUid
9066     */
9067    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9068        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9069        if (perms != null) {
9070            for (int i=perms.size()-1; i>=0; i--) {
9071                GrantUri grantUri = perms.keyAt(i);
9072                if (grantUri.sourceUserId == userId || !checkUser) {
9073                    if (matchesProvider(grantUri.uri, cpi)) {
9074                        return true;
9075                    }
9076                }
9077            }
9078        }
9079        return false;
9080    }
9081
9082    /**
9083     * Returns true if the uri authority is one of the authorities specified in the provider.
9084     */
9085    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9086        String uriAuth = uri.getAuthority();
9087        String cpiAuth = cpi.authority;
9088        if (cpiAuth.indexOf(';') == -1) {
9089            return cpiAuth.equals(uriAuth);
9090        }
9091        String[] cpiAuths = cpiAuth.split(";");
9092        int length = cpiAuths.length;
9093        for (int i = 0; i < length; i++) {
9094            if (cpiAuths[i].equals(uriAuth)) return true;
9095        }
9096        return false;
9097    }
9098
9099    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9100            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9101        if (r != null) {
9102            for (int i=0; i<r.conProviders.size(); i++) {
9103                ContentProviderConnection conn = r.conProviders.get(i);
9104                if (conn.provider == cpr) {
9105                    if (DEBUG_PROVIDER) Slog.v(TAG,
9106                            "Adding provider requested by "
9107                            + r.processName + " from process "
9108                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9109                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9110                    if (stable) {
9111                        conn.stableCount++;
9112                        conn.numStableIncs++;
9113                    } else {
9114                        conn.unstableCount++;
9115                        conn.numUnstableIncs++;
9116                    }
9117                    return conn;
9118                }
9119            }
9120            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9121            if (stable) {
9122                conn.stableCount = 1;
9123                conn.numStableIncs = 1;
9124            } else {
9125                conn.unstableCount = 1;
9126                conn.numUnstableIncs = 1;
9127            }
9128            cpr.connections.add(conn);
9129            r.conProviders.add(conn);
9130            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9131            return conn;
9132        }
9133        cpr.addExternalProcessHandleLocked(externalProcessToken);
9134        return null;
9135    }
9136
9137    boolean decProviderCountLocked(ContentProviderConnection conn,
9138            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9139        if (conn != null) {
9140            cpr = conn.provider;
9141            if (DEBUG_PROVIDER) Slog.v(TAG,
9142                    "Removing provider requested by "
9143                    + conn.client.processName + " from process "
9144                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9145                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9146            if (stable) {
9147                conn.stableCount--;
9148            } else {
9149                conn.unstableCount--;
9150            }
9151            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9152                cpr.connections.remove(conn);
9153                conn.client.conProviders.remove(conn);
9154                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9155                return true;
9156            }
9157            return false;
9158        }
9159        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9160        return false;
9161    }
9162
9163    private void checkTime(long startTime, String where) {
9164        long now = SystemClock.elapsedRealtime();
9165        if ((now-startTime) > 1000) {
9166            // If we are taking more than a second, log about it.
9167            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9168        }
9169    }
9170
9171    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9172            String name, IBinder token, boolean stable, int userId) {
9173        ContentProviderRecord cpr;
9174        ContentProviderConnection conn = null;
9175        ProviderInfo cpi = null;
9176
9177        synchronized(this) {
9178            long startTime = SystemClock.elapsedRealtime();
9179
9180            ProcessRecord r = null;
9181            if (caller != null) {
9182                r = getRecordForAppLocked(caller);
9183                if (r == null) {
9184                    throw new SecurityException(
9185                            "Unable to find app for caller " + caller
9186                          + " (pid=" + Binder.getCallingPid()
9187                          + ") when getting content provider " + name);
9188                }
9189            }
9190
9191            boolean checkCrossUser = true;
9192
9193            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9194
9195            // First check if this content provider has been published...
9196            cpr = mProviderMap.getProviderByName(name, userId);
9197            // If that didn't work, check if it exists for user 0 and then
9198            // verify that it's a singleton provider before using it.
9199            if (cpr == null && userId != UserHandle.USER_OWNER) {
9200                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9201                if (cpr != null) {
9202                    cpi = cpr.info;
9203                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9204                            cpi.name, cpi.flags)
9205                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9206                        userId = UserHandle.USER_OWNER;
9207                        checkCrossUser = false;
9208                    } else {
9209                        cpr = null;
9210                        cpi = null;
9211                    }
9212                }
9213            }
9214
9215            boolean providerRunning = cpr != null;
9216            if (providerRunning) {
9217                cpi = cpr.info;
9218                String msg;
9219                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9220                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9221                        != null) {
9222                    throw new SecurityException(msg);
9223                }
9224                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9225
9226                if (r != null && cpr.canRunHere(r)) {
9227                    // This provider has been published or is in the process
9228                    // of being published...  but it is also allowed to run
9229                    // in the caller's process, so don't make a connection
9230                    // and just let the caller instantiate its own instance.
9231                    ContentProviderHolder holder = cpr.newHolder(null);
9232                    // don't give caller the provider object, it needs
9233                    // to make its own.
9234                    holder.provider = null;
9235                    return holder;
9236                }
9237
9238                final long origId = Binder.clearCallingIdentity();
9239
9240                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9241
9242                // In this case the provider instance already exists, so we can
9243                // return it right away.
9244                conn = incProviderCountLocked(r, cpr, token, stable);
9245                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9246                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9247                        // If this is a perceptible app accessing the provider,
9248                        // make sure to count it as being accessed and thus
9249                        // back up on the LRU list.  This is good because
9250                        // content providers are often expensive to start.
9251                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9252                        updateLruProcessLocked(cpr.proc, false, null);
9253                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9254                    }
9255                }
9256
9257                if (cpr.proc != null) {
9258                    if (false) {
9259                        if (cpr.name.flattenToShortString().equals(
9260                                "com.android.providers.calendar/.CalendarProvider2")) {
9261                            Slog.v(TAG, "****************** KILLING "
9262                                + cpr.name.flattenToShortString());
9263                            Process.killProcess(cpr.proc.pid);
9264                        }
9265                    }
9266                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9267                    boolean success = updateOomAdjLocked(cpr.proc);
9268                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9269                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9270                    // NOTE: there is still a race here where a signal could be
9271                    // pending on the process even though we managed to update its
9272                    // adj level.  Not sure what to do about this, but at least
9273                    // the race is now smaller.
9274                    if (!success) {
9275                        // Uh oh...  it looks like the provider's process
9276                        // has been killed on us.  We need to wait for a new
9277                        // process to be started, and make sure its death
9278                        // doesn't kill our process.
9279                        Slog.i(TAG,
9280                                "Existing provider " + cpr.name.flattenToShortString()
9281                                + " is crashing; detaching " + r);
9282                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9283                        checkTime(startTime, "getContentProviderImpl: before appDied");
9284                        appDiedLocked(cpr.proc);
9285                        checkTime(startTime, "getContentProviderImpl: after appDied");
9286                        if (!lastRef) {
9287                            // This wasn't the last ref our process had on
9288                            // the provider...  we have now been killed, bail.
9289                            return null;
9290                        }
9291                        providerRunning = false;
9292                        conn = null;
9293                    }
9294                }
9295
9296                Binder.restoreCallingIdentity(origId);
9297            }
9298
9299            boolean singleton;
9300            if (!providerRunning) {
9301                try {
9302                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9303                    cpi = AppGlobals.getPackageManager().
9304                        resolveContentProvider(name,
9305                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9306                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9307                } catch (RemoteException ex) {
9308                }
9309                if (cpi == null) {
9310                    return null;
9311                }
9312                // If the provider is a singleton AND
9313                // (it's a call within the same user || the provider is a
9314                // privileged app)
9315                // Then allow connecting to the singleton provider
9316                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9317                        cpi.name, cpi.flags)
9318                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9319                if (singleton) {
9320                    userId = UserHandle.USER_OWNER;
9321                }
9322                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9323                checkTime(startTime, "getContentProviderImpl: got app info for user");
9324
9325                String msg;
9326                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9327                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9328                        != null) {
9329                    throw new SecurityException(msg);
9330                }
9331                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9332
9333                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9334                        && !cpi.processName.equals("system")) {
9335                    // If this content provider does not run in the system
9336                    // process, and the system is not yet ready to run other
9337                    // processes, then fail fast instead of hanging.
9338                    throw new IllegalArgumentException(
9339                            "Attempt to launch content provider before system ready");
9340                }
9341
9342                // Make sure that the user who owns this provider is running.  If not,
9343                // we don't want to allow it to run.
9344                if (!isUserRunningLocked(userId, false)) {
9345                    Slog.w(TAG, "Unable to launch app "
9346                            + cpi.applicationInfo.packageName + "/"
9347                            + cpi.applicationInfo.uid + " for provider "
9348                            + name + ": user " + userId + " is stopped");
9349                    return null;
9350                }
9351
9352                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9353                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9354                cpr = mProviderMap.getProviderByClass(comp, userId);
9355                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9356                final boolean firstClass = cpr == null;
9357                if (firstClass) {
9358                    final long ident = Binder.clearCallingIdentity();
9359                    try {
9360                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9361                        ApplicationInfo ai =
9362                            AppGlobals.getPackageManager().
9363                                getApplicationInfo(
9364                                        cpi.applicationInfo.packageName,
9365                                        STOCK_PM_FLAGS, userId);
9366                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9367                        if (ai == null) {
9368                            Slog.w(TAG, "No package info for content provider "
9369                                    + cpi.name);
9370                            return null;
9371                        }
9372                        ai = getAppInfoForUser(ai, userId);
9373                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9374                    } catch (RemoteException ex) {
9375                        // pm is in same process, this will never happen.
9376                    } finally {
9377                        Binder.restoreCallingIdentity(ident);
9378                    }
9379                }
9380
9381                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9382
9383                if (r != null && cpr.canRunHere(r)) {
9384                    // If this is a multiprocess provider, then just return its
9385                    // info and allow the caller to instantiate it.  Only do
9386                    // this if the provider is the same user as the caller's
9387                    // process, or can run as root (so can be in any process).
9388                    return cpr.newHolder(null);
9389                }
9390
9391                if (DEBUG_PROVIDER) {
9392                    RuntimeException e = new RuntimeException("here");
9393                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9394                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9395                }
9396
9397                // This is single process, and our app is now connecting to it.
9398                // See if we are already in the process of launching this
9399                // provider.
9400                final int N = mLaunchingProviders.size();
9401                int i;
9402                for (i=0; i<N; i++) {
9403                    if (mLaunchingProviders.get(i) == cpr) {
9404                        break;
9405                    }
9406                }
9407
9408                // If the provider is not already being launched, then get it
9409                // started.
9410                if (i >= N) {
9411                    final long origId = Binder.clearCallingIdentity();
9412
9413                    try {
9414                        // Content provider is now in use, its package can't be stopped.
9415                        try {
9416                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9417                            AppGlobals.getPackageManager().setPackageStoppedState(
9418                                    cpr.appInfo.packageName, false, userId);
9419                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9420                        } catch (RemoteException e) {
9421                        } catch (IllegalArgumentException e) {
9422                            Slog.w(TAG, "Failed trying to unstop package "
9423                                    + cpr.appInfo.packageName + ": " + e);
9424                        }
9425
9426                        // Use existing process if already started
9427                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9428                        ProcessRecord proc = getProcessRecordLocked(
9429                                cpi.processName, cpr.appInfo.uid, false);
9430                        if (proc != null && proc.thread != null) {
9431                            if (DEBUG_PROVIDER) {
9432                                Slog.d(TAG, "Installing in existing process " + proc);
9433                            }
9434                            if (!proc.pubProviders.containsKey(cpi.name)) {
9435                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9436                                proc.pubProviders.put(cpi.name, cpr);
9437                                try {
9438                                    proc.thread.scheduleInstallProvider(cpi);
9439                                } catch (RemoteException e) {
9440                                }
9441                            }
9442                        } else {
9443                            checkTime(startTime, "getContentProviderImpl: before start process");
9444                            proc = startProcessLocked(cpi.processName,
9445                                    cpr.appInfo, false, 0, "content provider",
9446                                    new ComponentName(cpi.applicationInfo.packageName,
9447                                            cpi.name), false, false, false);
9448                            checkTime(startTime, "getContentProviderImpl: after start process");
9449                            if (proc == null) {
9450                                Slog.w(TAG, "Unable to launch app "
9451                                        + cpi.applicationInfo.packageName + "/"
9452                                        + cpi.applicationInfo.uid + " for provider "
9453                                        + name + ": process is bad");
9454                                return null;
9455                            }
9456                        }
9457                        cpr.launchingApp = proc;
9458                        mLaunchingProviders.add(cpr);
9459                    } finally {
9460                        Binder.restoreCallingIdentity(origId);
9461                    }
9462                }
9463
9464                checkTime(startTime, "getContentProviderImpl: updating data structures");
9465
9466                // Make sure the provider is published (the same provider class
9467                // may be published under multiple names).
9468                if (firstClass) {
9469                    mProviderMap.putProviderByClass(comp, cpr);
9470                }
9471
9472                mProviderMap.putProviderByName(name, cpr);
9473                conn = incProviderCountLocked(r, cpr, token, stable);
9474                if (conn != null) {
9475                    conn.waiting = true;
9476                }
9477            }
9478            checkTime(startTime, "getContentProviderImpl: done!");
9479        }
9480
9481        // Wait for the provider to be published...
9482        synchronized (cpr) {
9483            while (cpr.provider == null) {
9484                if (cpr.launchingApp == null) {
9485                    Slog.w(TAG, "Unable to launch app "
9486                            + cpi.applicationInfo.packageName + "/"
9487                            + cpi.applicationInfo.uid + " for provider "
9488                            + name + ": launching app became null");
9489                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9490                            UserHandle.getUserId(cpi.applicationInfo.uid),
9491                            cpi.applicationInfo.packageName,
9492                            cpi.applicationInfo.uid, name);
9493                    return null;
9494                }
9495                try {
9496                    if (DEBUG_MU) {
9497                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9498                                + cpr.launchingApp);
9499                    }
9500                    if (conn != null) {
9501                        conn.waiting = true;
9502                    }
9503                    cpr.wait();
9504                } catch (InterruptedException ex) {
9505                } finally {
9506                    if (conn != null) {
9507                        conn.waiting = false;
9508                    }
9509                }
9510            }
9511        }
9512        return cpr != null ? cpr.newHolder(conn) : null;
9513    }
9514
9515    @Override
9516    public final ContentProviderHolder getContentProvider(
9517            IApplicationThread caller, String name, int userId, boolean stable) {
9518        enforceNotIsolatedCaller("getContentProvider");
9519        if (caller == null) {
9520            String msg = "null IApplicationThread when getting content provider "
9521                    + name;
9522            Slog.w(TAG, msg);
9523            throw new SecurityException(msg);
9524        }
9525        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9526        // with cross-user grant.
9527        return getContentProviderImpl(caller, name, null, stable, userId);
9528    }
9529
9530    public ContentProviderHolder getContentProviderExternal(
9531            String name, int userId, IBinder token) {
9532        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9533            "Do not have permission in call getContentProviderExternal()");
9534        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9535                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9536        return getContentProviderExternalUnchecked(name, token, userId);
9537    }
9538
9539    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9540            IBinder token, int userId) {
9541        return getContentProviderImpl(null, name, token, true, userId);
9542    }
9543
9544    /**
9545     * Drop a content provider from a ProcessRecord's bookkeeping
9546     */
9547    public void removeContentProvider(IBinder connection, boolean stable) {
9548        enforceNotIsolatedCaller("removeContentProvider");
9549        long ident = Binder.clearCallingIdentity();
9550        try {
9551            synchronized (this) {
9552                ContentProviderConnection conn;
9553                try {
9554                    conn = (ContentProviderConnection)connection;
9555                } catch (ClassCastException e) {
9556                    String msg ="removeContentProvider: " + connection
9557                            + " not a ContentProviderConnection";
9558                    Slog.w(TAG, msg);
9559                    throw new IllegalArgumentException(msg);
9560                }
9561                if (conn == null) {
9562                    throw new NullPointerException("connection is null");
9563                }
9564                if (decProviderCountLocked(conn, null, null, stable)) {
9565                    updateOomAdjLocked();
9566                }
9567            }
9568        } finally {
9569            Binder.restoreCallingIdentity(ident);
9570        }
9571    }
9572
9573    public void removeContentProviderExternal(String name, IBinder token) {
9574        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9575            "Do not have permission in call removeContentProviderExternal()");
9576        int userId = UserHandle.getCallingUserId();
9577        long ident = Binder.clearCallingIdentity();
9578        try {
9579            removeContentProviderExternalUnchecked(name, token, userId);
9580        } finally {
9581            Binder.restoreCallingIdentity(ident);
9582        }
9583    }
9584
9585    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9586        synchronized (this) {
9587            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9588            if(cpr == null) {
9589                //remove from mProvidersByClass
9590                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9591                return;
9592            }
9593
9594            //update content provider record entry info
9595            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9596            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9597            if (localCpr.hasExternalProcessHandles()) {
9598                if (localCpr.removeExternalProcessHandleLocked(token)) {
9599                    updateOomAdjLocked();
9600                } else {
9601                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9602                            + " with no external reference for token: "
9603                            + token + ".");
9604                }
9605            } else {
9606                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9607                        + " with no external references.");
9608            }
9609        }
9610    }
9611
9612    public final void publishContentProviders(IApplicationThread caller,
9613            List<ContentProviderHolder> providers) {
9614        if (providers == null) {
9615            return;
9616        }
9617
9618        enforceNotIsolatedCaller("publishContentProviders");
9619        synchronized (this) {
9620            final ProcessRecord r = getRecordForAppLocked(caller);
9621            if (DEBUG_MU)
9622                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9623            if (r == null) {
9624                throw new SecurityException(
9625                        "Unable to find app for caller " + caller
9626                      + " (pid=" + Binder.getCallingPid()
9627                      + ") when publishing content providers");
9628            }
9629
9630            final long origId = Binder.clearCallingIdentity();
9631
9632            final int N = providers.size();
9633            for (int i=0; i<N; i++) {
9634                ContentProviderHolder src = providers.get(i);
9635                if (src == null || src.info == null || src.provider == null) {
9636                    continue;
9637                }
9638                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9639                if (DEBUG_MU)
9640                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9641                if (dst != null) {
9642                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9643                    mProviderMap.putProviderByClass(comp, dst);
9644                    String names[] = dst.info.authority.split(";");
9645                    for (int j = 0; j < names.length; j++) {
9646                        mProviderMap.putProviderByName(names[j], dst);
9647                    }
9648
9649                    int NL = mLaunchingProviders.size();
9650                    int j;
9651                    for (j=0; j<NL; j++) {
9652                        if (mLaunchingProviders.get(j) == dst) {
9653                            mLaunchingProviders.remove(j);
9654                            j--;
9655                            NL--;
9656                        }
9657                    }
9658                    synchronized (dst) {
9659                        dst.provider = src.provider;
9660                        dst.proc = r;
9661                        dst.notifyAll();
9662                    }
9663                    updateOomAdjLocked(r);
9664                }
9665            }
9666
9667            Binder.restoreCallingIdentity(origId);
9668        }
9669    }
9670
9671    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9672        ContentProviderConnection conn;
9673        try {
9674            conn = (ContentProviderConnection)connection;
9675        } catch (ClassCastException e) {
9676            String msg ="refContentProvider: " + connection
9677                    + " not a ContentProviderConnection";
9678            Slog.w(TAG, msg);
9679            throw new IllegalArgumentException(msg);
9680        }
9681        if (conn == null) {
9682            throw new NullPointerException("connection is null");
9683        }
9684
9685        synchronized (this) {
9686            if (stable > 0) {
9687                conn.numStableIncs += stable;
9688            }
9689            stable = conn.stableCount + stable;
9690            if (stable < 0) {
9691                throw new IllegalStateException("stableCount < 0: " + stable);
9692            }
9693
9694            if (unstable > 0) {
9695                conn.numUnstableIncs += unstable;
9696            }
9697            unstable = conn.unstableCount + unstable;
9698            if (unstable < 0) {
9699                throw new IllegalStateException("unstableCount < 0: " + unstable);
9700            }
9701
9702            if ((stable+unstable) <= 0) {
9703                throw new IllegalStateException("ref counts can't go to zero here: stable="
9704                        + stable + " unstable=" + unstable);
9705            }
9706            conn.stableCount = stable;
9707            conn.unstableCount = unstable;
9708            return !conn.dead;
9709        }
9710    }
9711
9712    public void unstableProviderDied(IBinder connection) {
9713        ContentProviderConnection conn;
9714        try {
9715            conn = (ContentProviderConnection)connection;
9716        } catch (ClassCastException e) {
9717            String msg ="refContentProvider: " + connection
9718                    + " not a ContentProviderConnection";
9719            Slog.w(TAG, msg);
9720            throw new IllegalArgumentException(msg);
9721        }
9722        if (conn == null) {
9723            throw new NullPointerException("connection is null");
9724        }
9725
9726        // Safely retrieve the content provider associated with the connection.
9727        IContentProvider provider;
9728        synchronized (this) {
9729            provider = conn.provider.provider;
9730        }
9731
9732        if (provider == null) {
9733            // Um, yeah, we're way ahead of you.
9734            return;
9735        }
9736
9737        // Make sure the caller is being honest with us.
9738        if (provider.asBinder().pingBinder()) {
9739            // Er, no, still looks good to us.
9740            synchronized (this) {
9741                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9742                        + " says " + conn + " died, but we don't agree");
9743                return;
9744            }
9745        }
9746
9747        // Well look at that!  It's dead!
9748        synchronized (this) {
9749            if (conn.provider.provider != provider) {
9750                // But something changed...  good enough.
9751                return;
9752            }
9753
9754            ProcessRecord proc = conn.provider.proc;
9755            if (proc == null || proc.thread == null) {
9756                // Seems like the process is already cleaned up.
9757                return;
9758            }
9759
9760            // As far as we're concerned, this is just like receiving a
9761            // death notification...  just a bit prematurely.
9762            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9763                    + ") early provider death");
9764            final long ident = Binder.clearCallingIdentity();
9765            try {
9766                appDiedLocked(proc);
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771    }
9772
9773    @Override
9774    public void appNotRespondingViaProvider(IBinder connection) {
9775        enforceCallingPermission(
9776                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9777
9778        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9779        if (conn == null) {
9780            Slog.w(TAG, "ContentProviderConnection is null");
9781            return;
9782        }
9783
9784        final ProcessRecord host = conn.provider.proc;
9785        if (host == null) {
9786            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9787            return;
9788        }
9789
9790        final long token = Binder.clearCallingIdentity();
9791        try {
9792            appNotResponding(host, null, null, false, "ContentProvider not responding");
9793        } finally {
9794            Binder.restoreCallingIdentity(token);
9795        }
9796    }
9797
9798    public final void installSystemProviders() {
9799        List<ProviderInfo> providers;
9800        synchronized (this) {
9801            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9802            providers = generateApplicationProvidersLocked(app);
9803            if (providers != null) {
9804                for (int i=providers.size()-1; i>=0; i--) {
9805                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9806                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9807                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9808                                + ": not system .apk");
9809                        providers.remove(i);
9810                    }
9811                }
9812            }
9813        }
9814        if (providers != null) {
9815            mSystemThread.installSystemProviders(providers);
9816        }
9817
9818        mCoreSettingsObserver = new CoreSettingsObserver(this);
9819
9820        //mUsageStatsService.monitorPackages();
9821    }
9822
9823    /**
9824     * Allows apps to retrieve the MIME type of a URI.
9825     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9826     * users, then it does not need permission to access the ContentProvider.
9827     * Either, it needs cross-user uri grants.
9828     *
9829     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9830     *
9831     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9832     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9833     */
9834    public String getProviderMimeType(Uri uri, int userId) {
9835        enforceNotIsolatedCaller("getProviderMimeType");
9836        final String name = uri.getAuthority();
9837        int callingUid = Binder.getCallingUid();
9838        int callingPid = Binder.getCallingPid();
9839        long ident = 0;
9840        boolean clearedIdentity = false;
9841        userId = unsafeConvertIncomingUser(userId);
9842        if (canClearIdentity(callingPid, callingUid, userId)) {
9843            clearedIdentity = true;
9844            ident = Binder.clearCallingIdentity();
9845        }
9846        ContentProviderHolder holder = null;
9847        try {
9848            holder = getContentProviderExternalUnchecked(name, null, userId);
9849            if (holder != null) {
9850                return holder.provider.getType(uri);
9851            }
9852        } catch (RemoteException e) {
9853            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9854            return null;
9855        } finally {
9856            // We need to clear the identity to call removeContentProviderExternalUnchecked
9857            if (!clearedIdentity) {
9858                ident = Binder.clearCallingIdentity();
9859            }
9860            try {
9861                if (holder != null) {
9862                    removeContentProviderExternalUnchecked(name, null, userId);
9863                }
9864            } finally {
9865                Binder.restoreCallingIdentity(ident);
9866            }
9867        }
9868
9869        return null;
9870    }
9871
9872    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9873        if (UserHandle.getUserId(callingUid) == userId) {
9874            return true;
9875        }
9876        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9877                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9878                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9879                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9880                return true;
9881        }
9882        return false;
9883    }
9884
9885    // =========================================================
9886    // GLOBAL MANAGEMENT
9887    // =========================================================
9888
9889    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9890            boolean isolated, int isolatedUid) {
9891        String proc = customProcess != null ? customProcess : info.processName;
9892        BatteryStatsImpl.Uid.Proc ps = null;
9893        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9894        int uid = info.uid;
9895        if (isolated) {
9896            if (isolatedUid == 0) {
9897                int userId = UserHandle.getUserId(uid);
9898                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9899                while (true) {
9900                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9901                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9902                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9903                    }
9904                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9905                    mNextIsolatedProcessUid++;
9906                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9907                        // No process for this uid, use it.
9908                        break;
9909                    }
9910                    stepsLeft--;
9911                    if (stepsLeft <= 0) {
9912                        return null;
9913                    }
9914                }
9915            } else {
9916                // Special case for startIsolatedProcess (internal only), where
9917                // the uid of the isolated process is specified by the caller.
9918                uid = isolatedUid;
9919            }
9920        }
9921        return new ProcessRecord(stats, info, proc, uid);
9922    }
9923
9924    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9925            String abiOverride) {
9926        ProcessRecord app;
9927        if (!isolated) {
9928            app = getProcessRecordLocked(info.processName, info.uid, true);
9929        } else {
9930            app = null;
9931        }
9932
9933        if (app == null) {
9934            app = newProcessRecordLocked(info, null, isolated, 0);
9935            mProcessNames.put(info.processName, app.uid, app);
9936            if (isolated) {
9937                mIsolatedProcesses.put(app.uid, app);
9938            }
9939            updateLruProcessLocked(app, false, null);
9940            updateOomAdjLocked();
9941        }
9942
9943        // This package really, really can not be stopped.
9944        try {
9945            AppGlobals.getPackageManager().setPackageStoppedState(
9946                    info.packageName, false, UserHandle.getUserId(app.uid));
9947        } catch (RemoteException e) {
9948        } catch (IllegalArgumentException e) {
9949            Slog.w(TAG, "Failed trying to unstop package "
9950                    + info.packageName + ": " + e);
9951        }
9952
9953        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9954                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9955            app.persistent = true;
9956            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9957        }
9958        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9959            mPersistentStartingProcesses.add(app);
9960            startProcessLocked(app, "added application", app.processName, abiOverride,
9961                    null /* entryPoint */, null /* entryPointArgs */);
9962        }
9963
9964        return app;
9965    }
9966
9967    public void unhandledBack() {
9968        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9969                "unhandledBack()");
9970
9971        synchronized(this) {
9972            final long origId = Binder.clearCallingIdentity();
9973            try {
9974                getFocusedStack().unhandledBackLocked();
9975            } finally {
9976                Binder.restoreCallingIdentity(origId);
9977            }
9978        }
9979    }
9980
9981    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9982        enforceNotIsolatedCaller("openContentUri");
9983        final int userId = UserHandle.getCallingUserId();
9984        String name = uri.getAuthority();
9985        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9986        ParcelFileDescriptor pfd = null;
9987        if (cph != null) {
9988            // We record the binder invoker's uid in thread-local storage before
9989            // going to the content provider to open the file.  Later, in the code
9990            // that handles all permissions checks, we look for this uid and use
9991            // that rather than the Activity Manager's own uid.  The effect is that
9992            // we do the check against the caller's permissions even though it looks
9993            // to the content provider like the Activity Manager itself is making
9994            // the request.
9995            Binder token = new Binder();
9996            sCallerIdentity.set(new Identity(
9997                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9998            try {
9999                pfd = cph.provider.openFile(null, uri, "r", null, token);
10000            } catch (FileNotFoundException e) {
10001                // do nothing; pfd will be returned null
10002            } finally {
10003                // Ensure that whatever happens, we clean up the identity state
10004                sCallerIdentity.remove();
10005                // Ensure we're done with the provider.
10006                removeContentProviderExternalUnchecked(name, null, userId);
10007            }
10008        } else {
10009            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10010        }
10011        return pfd;
10012    }
10013
10014    // Actually is sleeping or shutting down or whatever else in the future
10015    // is an inactive state.
10016    public boolean isSleepingOrShuttingDown() {
10017        return isSleeping() || mShuttingDown;
10018    }
10019
10020    public boolean isSleeping() {
10021        return mSleeping;
10022    }
10023
10024    void onWakefulnessChanged(int wakefulness) {
10025        synchronized(this) {
10026            mWakefulness = wakefulness;
10027            updateSleepIfNeededLocked();
10028        }
10029    }
10030
10031    void finishRunningVoiceLocked() {
10032        if (mRunningVoice) {
10033            mRunningVoice = false;
10034            updateSleepIfNeededLocked();
10035        }
10036    }
10037
10038    void updateSleepIfNeededLocked() {
10039        if (mSleeping && !shouldSleepLocked()) {
10040            mSleeping = false;
10041            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10042        } else if (!mSleeping && shouldSleepLocked()) {
10043            mSleeping = true;
10044            mStackSupervisor.goingToSleepLocked();
10045
10046            // Initialize the wake times of all processes.
10047            checkExcessivePowerUsageLocked(false);
10048            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10049            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10050            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10051        }
10052    }
10053
10054    private boolean shouldSleepLocked() {
10055        // Resume applications while running a voice interactor.
10056        if (mRunningVoice) {
10057            return false;
10058        }
10059
10060        switch (mWakefulness) {
10061            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10062            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10063                // If we're interactive but applications are already paused then defer
10064                // resuming them until the lock screen is hidden.
10065                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10066            case PowerManagerInternal.WAKEFULNESS_DOZING:
10067                // If we're dozing then pause applications whenever the lock screen is shown.
10068                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10069            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10070            default:
10071                // If we're asleep then pause applications unconditionally.
10072                return true;
10073        }
10074    }
10075
10076    /** Pokes the task persister. */
10077    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10078        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10079            // Never persist the home stack.
10080            return;
10081        }
10082        mTaskPersister.wakeup(task, flush);
10083    }
10084
10085    /** Notifies all listeners when the task stack has changed. */
10086    void notifyTaskStackChangedLocked() {
10087        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10088        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10089        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10090    }
10091
10092    @Override
10093    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10094        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10095    }
10096
10097    @Override
10098    public boolean shutdown(int timeout) {
10099        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10100                != PackageManager.PERMISSION_GRANTED) {
10101            throw new SecurityException("Requires permission "
10102                    + android.Manifest.permission.SHUTDOWN);
10103        }
10104
10105        boolean timedout = false;
10106
10107        synchronized(this) {
10108            mShuttingDown = true;
10109            updateEventDispatchingLocked();
10110            timedout = mStackSupervisor.shutdownLocked(timeout);
10111        }
10112
10113        mAppOpsService.shutdown();
10114        if (mUsageStatsService != null) {
10115            mUsageStatsService.prepareShutdown();
10116        }
10117        mBatteryStatsService.shutdown();
10118        synchronized (this) {
10119            mProcessStats.shutdownLocked();
10120            notifyTaskPersisterLocked(null, true);
10121        }
10122
10123        return timedout;
10124    }
10125
10126    public final void activitySlept(IBinder token) {
10127        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10128
10129        final long origId = Binder.clearCallingIdentity();
10130
10131        synchronized (this) {
10132            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10133            if (r != null) {
10134                mStackSupervisor.activitySleptLocked(r);
10135            }
10136        }
10137
10138        Binder.restoreCallingIdentity(origId);
10139    }
10140
10141    private String lockScreenShownToString() {
10142        switch (mLockScreenShown) {
10143            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10144            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10145            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10146            default: return "Unknown=" + mLockScreenShown;
10147        }
10148    }
10149
10150    void logLockScreen(String msg) {
10151        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10152                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10153                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10154                + " mSleeping=" + mSleeping);
10155    }
10156
10157    void startRunningVoiceLocked() {
10158        if (!mRunningVoice) {
10159            mRunningVoice = true;
10160            updateSleepIfNeededLocked();
10161        }
10162    }
10163
10164    private void updateEventDispatchingLocked() {
10165        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10166    }
10167
10168    public void setLockScreenShown(boolean shown) {
10169        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10170                != PackageManager.PERMISSION_GRANTED) {
10171            throw new SecurityException("Requires permission "
10172                    + android.Manifest.permission.DEVICE_POWER);
10173        }
10174
10175        synchronized(this) {
10176            long ident = Binder.clearCallingIdentity();
10177            try {
10178                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10179                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10180                updateSleepIfNeededLocked();
10181            } finally {
10182                Binder.restoreCallingIdentity(ident);
10183            }
10184        }
10185    }
10186
10187    @Override
10188    public void stopAppSwitches() {
10189        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10190                != PackageManager.PERMISSION_GRANTED) {
10191            throw new SecurityException("Requires permission "
10192                    + android.Manifest.permission.STOP_APP_SWITCHES);
10193        }
10194
10195        synchronized(this) {
10196            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10197                    + APP_SWITCH_DELAY_TIME;
10198            mDidAppSwitch = false;
10199            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10200            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10201            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10202        }
10203    }
10204
10205    public void resumeAppSwitches() {
10206        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10207                != PackageManager.PERMISSION_GRANTED) {
10208            throw new SecurityException("Requires permission "
10209                    + android.Manifest.permission.STOP_APP_SWITCHES);
10210        }
10211
10212        synchronized(this) {
10213            // Note that we don't execute any pending app switches... we will
10214            // let those wait until either the timeout, or the next start
10215            // activity request.
10216            mAppSwitchesAllowedTime = 0;
10217        }
10218    }
10219
10220    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10221            int callingPid, int callingUid, String name) {
10222        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10223            return true;
10224        }
10225
10226        int perm = checkComponentPermission(
10227                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10228                sourceUid, -1, true);
10229        if (perm == PackageManager.PERMISSION_GRANTED) {
10230            return true;
10231        }
10232
10233        // If the actual IPC caller is different from the logical source, then
10234        // also see if they are allowed to control app switches.
10235        if (callingUid != -1 && callingUid != sourceUid) {
10236            perm = checkComponentPermission(
10237                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10238                    callingUid, -1, true);
10239            if (perm == PackageManager.PERMISSION_GRANTED) {
10240                return true;
10241            }
10242        }
10243
10244        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10245        return false;
10246    }
10247
10248    public void setDebugApp(String packageName, boolean waitForDebugger,
10249            boolean persistent) {
10250        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10251                "setDebugApp()");
10252
10253        long ident = Binder.clearCallingIdentity();
10254        try {
10255            // Note that this is not really thread safe if there are multiple
10256            // callers into it at the same time, but that's not a situation we
10257            // care about.
10258            if (persistent) {
10259                final ContentResolver resolver = mContext.getContentResolver();
10260                Settings.Global.putString(
10261                    resolver, Settings.Global.DEBUG_APP,
10262                    packageName);
10263                Settings.Global.putInt(
10264                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10265                    waitForDebugger ? 1 : 0);
10266            }
10267
10268            synchronized (this) {
10269                if (!persistent) {
10270                    mOrigDebugApp = mDebugApp;
10271                    mOrigWaitForDebugger = mWaitForDebugger;
10272                }
10273                mDebugApp = packageName;
10274                mWaitForDebugger = waitForDebugger;
10275                mDebugTransient = !persistent;
10276                if (packageName != null) {
10277                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10278                            false, UserHandle.USER_ALL, "set debug app");
10279                }
10280            }
10281        } finally {
10282            Binder.restoreCallingIdentity(ident);
10283        }
10284    }
10285
10286    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10287        synchronized (this) {
10288            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10289            if (!isDebuggable) {
10290                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10291                    throw new SecurityException("Process not debuggable: " + app.packageName);
10292                }
10293            }
10294
10295            mOpenGlTraceApp = processName;
10296        }
10297    }
10298
10299    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10300        synchronized (this) {
10301            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10302            if (!isDebuggable) {
10303                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10304                    throw new SecurityException("Process not debuggable: " + app.packageName);
10305                }
10306            }
10307            mProfileApp = processName;
10308            mProfileFile = profilerInfo.profileFile;
10309            if (mProfileFd != null) {
10310                try {
10311                    mProfileFd.close();
10312                } catch (IOException e) {
10313                }
10314                mProfileFd = null;
10315            }
10316            mProfileFd = profilerInfo.profileFd;
10317            mSamplingInterval = profilerInfo.samplingInterval;
10318            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10319            mProfileType = 0;
10320        }
10321    }
10322
10323    @Override
10324    public void setAlwaysFinish(boolean enabled) {
10325        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10326                "setAlwaysFinish()");
10327
10328        Settings.Global.putInt(
10329                mContext.getContentResolver(),
10330                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10331
10332        synchronized (this) {
10333            mAlwaysFinishActivities = enabled;
10334        }
10335    }
10336
10337    @Override
10338    public void setActivityController(IActivityController controller) {
10339        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10340                "setActivityController()");
10341        synchronized (this) {
10342            mController = controller;
10343            Watchdog.getInstance().setActivityController(controller);
10344        }
10345    }
10346
10347    @Override
10348    public void setUserIsMonkey(boolean userIsMonkey) {
10349        synchronized (this) {
10350            synchronized (mPidsSelfLocked) {
10351                final int callingPid = Binder.getCallingPid();
10352                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10353                if (precessRecord == null) {
10354                    throw new SecurityException("Unknown process: " + callingPid);
10355                }
10356                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10357                    throw new SecurityException("Only an instrumentation process "
10358                            + "with a UiAutomation can call setUserIsMonkey");
10359                }
10360            }
10361            mUserIsMonkey = userIsMonkey;
10362        }
10363    }
10364
10365    @Override
10366    public boolean isUserAMonkey() {
10367        synchronized (this) {
10368            // If there is a controller also implies the user is a monkey.
10369            return (mUserIsMonkey || mController != null);
10370        }
10371    }
10372
10373    public void requestBugReport() {
10374        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10375        SystemProperties.set("ctl.start", "bugreport");
10376    }
10377
10378    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10379        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10380    }
10381
10382    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10383        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10384            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10385        }
10386        return KEY_DISPATCHING_TIMEOUT;
10387    }
10388
10389    @Override
10390    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10391        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10392                != PackageManager.PERMISSION_GRANTED) {
10393            throw new SecurityException("Requires permission "
10394                    + android.Manifest.permission.FILTER_EVENTS);
10395        }
10396        ProcessRecord proc;
10397        long timeout;
10398        synchronized (this) {
10399            synchronized (mPidsSelfLocked) {
10400                proc = mPidsSelfLocked.get(pid);
10401            }
10402            timeout = getInputDispatchingTimeoutLocked(proc);
10403        }
10404
10405        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10406            return -1;
10407        }
10408
10409        return timeout;
10410    }
10411
10412    /**
10413     * Handle input dispatching timeouts.
10414     * Returns whether input dispatching should be aborted or not.
10415     */
10416    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10417            final ActivityRecord activity, final ActivityRecord parent,
10418            final boolean aboveSystem, String reason) {
10419        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10420                != PackageManager.PERMISSION_GRANTED) {
10421            throw new SecurityException("Requires permission "
10422                    + android.Manifest.permission.FILTER_EVENTS);
10423        }
10424
10425        final String annotation;
10426        if (reason == null) {
10427            annotation = "Input dispatching timed out";
10428        } else {
10429            annotation = "Input dispatching timed out (" + reason + ")";
10430        }
10431
10432        if (proc != null) {
10433            synchronized (this) {
10434                if (proc.debugging) {
10435                    return false;
10436                }
10437
10438                if (mDidDexOpt) {
10439                    // Give more time since we were dexopting.
10440                    mDidDexOpt = false;
10441                    return false;
10442                }
10443
10444                if (proc.instrumentationClass != null) {
10445                    Bundle info = new Bundle();
10446                    info.putString("shortMsg", "keyDispatchingTimedOut");
10447                    info.putString("longMsg", annotation);
10448                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10449                    return true;
10450                }
10451            }
10452            mHandler.post(new Runnable() {
10453                @Override
10454                public void run() {
10455                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10456                }
10457            });
10458        }
10459
10460        return true;
10461    }
10462
10463    public Bundle getAssistContextExtras(int requestType) {
10464        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10465                UserHandle.getCallingUserId());
10466        if (pae == null) {
10467            return null;
10468        }
10469        synchronized (pae) {
10470            while (!pae.haveResult) {
10471                try {
10472                    pae.wait();
10473                } catch (InterruptedException e) {
10474                }
10475            }
10476            if (pae.result != null) {
10477                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10478            }
10479        }
10480        synchronized (this) {
10481            mPendingAssistExtras.remove(pae);
10482            mHandler.removeCallbacks(pae);
10483        }
10484        return pae.extras;
10485    }
10486
10487    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10488            int userHandle) {
10489        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10490                "getAssistContextExtras()");
10491        PendingAssistExtras pae;
10492        Bundle extras = new Bundle();
10493        synchronized (this) {
10494            ActivityRecord activity = getFocusedStack().mResumedActivity;
10495            if (activity == null) {
10496                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10497                return null;
10498            }
10499            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10500            if (activity.app == null || activity.app.thread == null) {
10501                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10502                return null;
10503            }
10504            if (activity.app.pid == Binder.getCallingPid()) {
10505                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10506                return null;
10507            }
10508            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10509            try {
10510                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10511                        requestType);
10512                mPendingAssistExtras.add(pae);
10513                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10514            } catch (RemoteException e) {
10515                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10516                return null;
10517            }
10518            return pae;
10519        }
10520    }
10521
10522    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10523        PendingAssistExtras pae = (PendingAssistExtras)token;
10524        synchronized (pae) {
10525            pae.result = extras;
10526            pae.haveResult = true;
10527            pae.notifyAll();
10528            if (pae.intent == null) {
10529                // Caller is just waiting for the result.
10530                return;
10531            }
10532        }
10533
10534        // We are now ready to launch the assist activity.
10535        synchronized (this) {
10536            boolean exists = mPendingAssistExtras.remove(pae);
10537            mHandler.removeCallbacks(pae);
10538            if (!exists) {
10539                // Timed out.
10540                return;
10541            }
10542        }
10543        pae.intent.replaceExtras(extras);
10544        if (pae.hint != null) {
10545            pae.intent.putExtra(pae.hint, true);
10546        }
10547        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10548                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10549                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10550        closeSystemDialogs("assist");
10551        try {
10552            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10553        } catch (ActivityNotFoundException e) {
10554            Slog.w(TAG, "No activity to handle assist action.", e);
10555        }
10556    }
10557
10558    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10559        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10560    }
10561
10562    public void registerProcessObserver(IProcessObserver observer) {
10563        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10564                "registerProcessObserver()");
10565        synchronized (this) {
10566            mProcessObservers.register(observer);
10567        }
10568    }
10569
10570    @Override
10571    public void unregisterProcessObserver(IProcessObserver observer) {
10572        synchronized (this) {
10573            mProcessObservers.unregister(observer);
10574        }
10575    }
10576
10577    @Override
10578    public boolean convertFromTranslucent(IBinder token) {
10579        final long origId = Binder.clearCallingIdentity();
10580        try {
10581            synchronized (this) {
10582                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10583                if (r == null) {
10584                    return false;
10585                }
10586                final boolean translucentChanged = r.changeWindowTranslucency(true);
10587                if (translucentChanged) {
10588                    r.task.stack.releaseBackgroundResources();
10589                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10590                }
10591                mWindowManager.setAppFullscreen(token, true);
10592                return translucentChanged;
10593            }
10594        } finally {
10595            Binder.restoreCallingIdentity(origId);
10596        }
10597    }
10598
10599    @Override
10600    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10601        final long origId = Binder.clearCallingIdentity();
10602        try {
10603            synchronized (this) {
10604                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10605                if (r == null) {
10606                    return false;
10607                }
10608                int index = r.task.mActivities.lastIndexOf(r);
10609                if (index > 0) {
10610                    ActivityRecord under = r.task.mActivities.get(index - 1);
10611                    under.returningOptions = options;
10612                }
10613                final boolean translucentChanged = r.changeWindowTranslucency(false);
10614                if (translucentChanged) {
10615                    r.task.stack.convertToTranslucent(r);
10616                }
10617                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10618                mWindowManager.setAppFullscreen(token, false);
10619                return translucentChanged;
10620            }
10621        } finally {
10622            Binder.restoreCallingIdentity(origId);
10623        }
10624    }
10625
10626    @Override
10627    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10628        final long origId = Binder.clearCallingIdentity();
10629        try {
10630            synchronized (this) {
10631                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10632                if (r != null) {
10633                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10634                }
10635            }
10636            return false;
10637        } finally {
10638            Binder.restoreCallingIdentity(origId);
10639        }
10640    }
10641
10642    @Override
10643    public boolean isBackgroundVisibleBehind(IBinder token) {
10644        final long origId = Binder.clearCallingIdentity();
10645        try {
10646            synchronized (this) {
10647                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10648                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10649                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10650                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10651                return visible;
10652            }
10653        } finally {
10654            Binder.restoreCallingIdentity(origId);
10655        }
10656    }
10657
10658    @Override
10659    public ActivityOptions getActivityOptions(IBinder token) {
10660        final long origId = Binder.clearCallingIdentity();
10661        try {
10662            synchronized (this) {
10663                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10664                if (r != null) {
10665                    final ActivityOptions activityOptions = r.pendingOptions;
10666                    r.pendingOptions = null;
10667                    return activityOptions;
10668                }
10669                return null;
10670            }
10671        } finally {
10672            Binder.restoreCallingIdentity(origId);
10673        }
10674    }
10675
10676    @Override
10677    public void setImmersive(IBinder token, boolean immersive) {
10678        synchronized(this) {
10679            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10680            if (r == null) {
10681                throw new IllegalArgumentException();
10682            }
10683            r.immersive = immersive;
10684
10685            // update associated state if we're frontmost
10686            if (r == mFocusedActivity) {
10687                if (DEBUG_IMMERSIVE) {
10688                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10689                }
10690                applyUpdateLockStateLocked(r);
10691            }
10692        }
10693    }
10694
10695    @Override
10696    public boolean isImmersive(IBinder token) {
10697        synchronized (this) {
10698            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10699            if (r == null) {
10700                throw new IllegalArgumentException();
10701            }
10702            return r.immersive;
10703        }
10704    }
10705
10706    public boolean isTopActivityImmersive() {
10707        enforceNotIsolatedCaller("startActivity");
10708        synchronized (this) {
10709            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10710            return (r != null) ? r.immersive : false;
10711        }
10712    }
10713
10714    @Override
10715    public boolean isTopOfTask(IBinder token) {
10716        synchronized (this) {
10717            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10718            if (r == null) {
10719                throw new IllegalArgumentException();
10720            }
10721            return r.task.getTopActivity() == r;
10722        }
10723    }
10724
10725    public final void enterSafeMode() {
10726        synchronized(this) {
10727            // It only makes sense to do this before the system is ready
10728            // and started launching other packages.
10729            if (!mSystemReady) {
10730                try {
10731                    AppGlobals.getPackageManager().enterSafeMode();
10732                } catch (RemoteException e) {
10733                }
10734            }
10735
10736            mSafeMode = true;
10737        }
10738    }
10739
10740    public final void showSafeModeOverlay() {
10741        View v = LayoutInflater.from(mContext).inflate(
10742                com.android.internal.R.layout.safe_mode, null);
10743        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10744        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10745        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10746        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10747        lp.gravity = Gravity.BOTTOM | Gravity.START;
10748        lp.format = v.getBackground().getOpacity();
10749        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10750                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10751        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10752        ((WindowManager)mContext.getSystemService(
10753                Context.WINDOW_SERVICE)).addView(v, lp);
10754    }
10755
10756    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10757        if (!(sender instanceof PendingIntentRecord)) {
10758            return;
10759        }
10760        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10761        synchronized (stats) {
10762            if (mBatteryStatsService.isOnBattery()) {
10763                mBatteryStatsService.enforceCallingPermission();
10764                PendingIntentRecord rec = (PendingIntentRecord)sender;
10765                int MY_UID = Binder.getCallingUid();
10766                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10767                BatteryStatsImpl.Uid.Pkg pkg =
10768                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10769                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10770                pkg.incWakeupsLocked();
10771            }
10772        }
10773    }
10774
10775    public boolean killPids(int[] pids, String pReason, boolean secure) {
10776        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10777            throw new SecurityException("killPids only available to the system");
10778        }
10779        String reason = (pReason == null) ? "Unknown" : pReason;
10780        // XXX Note: don't acquire main activity lock here, because the window
10781        // manager calls in with its locks held.
10782
10783        boolean killed = false;
10784        synchronized (mPidsSelfLocked) {
10785            int[] types = new int[pids.length];
10786            int worstType = 0;
10787            for (int i=0; i<pids.length; i++) {
10788                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10789                if (proc != null) {
10790                    int type = proc.setAdj;
10791                    types[i] = type;
10792                    if (type > worstType) {
10793                        worstType = type;
10794                    }
10795                }
10796            }
10797
10798            // If the worst oom_adj is somewhere in the cached proc LRU range,
10799            // then constrain it so we will kill all cached procs.
10800            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10801                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10802                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10803            }
10804
10805            // If this is not a secure call, don't let it kill processes that
10806            // are important.
10807            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10808                worstType = ProcessList.SERVICE_ADJ;
10809            }
10810
10811            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10812            for (int i=0; i<pids.length; i++) {
10813                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10814                if (proc == null) {
10815                    continue;
10816                }
10817                int adj = proc.setAdj;
10818                if (adj >= worstType && !proc.killedByAm) {
10819                    proc.kill(reason, true);
10820                    killed = true;
10821                }
10822            }
10823        }
10824        return killed;
10825    }
10826
10827    @Override
10828    public void killUid(int uid, String reason) {
10829        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10830            throw new SecurityException("killUid only available to the system");
10831        }
10832        synchronized (this) {
10833            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10834                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10835                    reason != null ? reason : "kill uid");
10836        }
10837    }
10838
10839    @Override
10840    public boolean killProcessesBelowForeground(String reason) {
10841        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10842            throw new SecurityException("killProcessesBelowForeground() only available to system");
10843        }
10844
10845        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10846    }
10847
10848    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10849        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10850            throw new SecurityException("killProcessesBelowAdj() only available to system");
10851        }
10852
10853        boolean killed = false;
10854        synchronized (mPidsSelfLocked) {
10855            final int size = mPidsSelfLocked.size();
10856            for (int i = 0; i < size; i++) {
10857                final int pid = mPidsSelfLocked.keyAt(i);
10858                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10859                if (proc == null) continue;
10860
10861                final int adj = proc.setAdj;
10862                if (adj > belowAdj && !proc.killedByAm) {
10863                    proc.kill(reason, true);
10864                    killed = true;
10865                }
10866            }
10867        }
10868        return killed;
10869    }
10870
10871    @Override
10872    public void hang(final IBinder who, boolean allowRestart) {
10873        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10874                != PackageManager.PERMISSION_GRANTED) {
10875            throw new SecurityException("Requires permission "
10876                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10877        }
10878
10879        final IBinder.DeathRecipient death = new DeathRecipient() {
10880            @Override
10881            public void binderDied() {
10882                synchronized (this) {
10883                    notifyAll();
10884                }
10885            }
10886        };
10887
10888        try {
10889            who.linkToDeath(death, 0);
10890        } catch (RemoteException e) {
10891            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10892            return;
10893        }
10894
10895        synchronized (this) {
10896            Watchdog.getInstance().setAllowRestart(allowRestart);
10897            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10898            synchronized (death) {
10899                while (who.isBinderAlive()) {
10900                    try {
10901                        death.wait();
10902                    } catch (InterruptedException e) {
10903                    }
10904                }
10905            }
10906            Watchdog.getInstance().setAllowRestart(true);
10907        }
10908    }
10909
10910    @Override
10911    public void restart() {
10912        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10913                != PackageManager.PERMISSION_GRANTED) {
10914            throw new SecurityException("Requires permission "
10915                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10916        }
10917
10918        Log.i(TAG, "Sending shutdown broadcast...");
10919
10920        BroadcastReceiver br = new BroadcastReceiver() {
10921            @Override public void onReceive(Context context, Intent intent) {
10922                // Now the broadcast is done, finish up the low-level shutdown.
10923                Log.i(TAG, "Shutting down activity manager...");
10924                shutdown(10000);
10925                Log.i(TAG, "Shutdown complete, restarting!");
10926                Process.killProcess(Process.myPid());
10927                System.exit(10);
10928            }
10929        };
10930
10931        // First send the high-level shut down broadcast.
10932        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10933        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10934        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10935        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10936        mContext.sendOrderedBroadcastAsUser(intent,
10937                UserHandle.ALL, null, br, mHandler, 0, null, null);
10938        */
10939        br.onReceive(mContext, intent);
10940    }
10941
10942    private long getLowRamTimeSinceIdle(long now) {
10943        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10944    }
10945
10946    @Override
10947    public void performIdleMaintenance() {
10948        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10949                != PackageManager.PERMISSION_GRANTED) {
10950            throw new SecurityException("Requires permission "
10951                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10952        }
10953
10954        synchronized (this) {
10955            final long now = SystemClock.uptimeMillis();
10956            final long timeSinceLastIdle = now - mLastIdleTime;
10957            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10958            mLastIdleTime = now;
10959            mLowRamTimeSinceLastIdle = 0;
10960            if (mLowRamStartTime != 0) {
10961                mLowRamStartTime = now;
10962            }
10963
10964            StringBuilder sb = new StringBuilder(128);
10965            sb.append("Idle maintenance over ");
10966            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10967            sb.append(" low RAM for ");
10968            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10969            Slog.i(TAG, sb.toString());
10970
10971            // If at least 1/3 of our time since the last idle period has been spent
10972            // with RAM low, then we want to kill processes.
10973            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10974
10975            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10976                ProcessRecord proc = mLruProcesses.get(i);
10977                if (proc.notCachedSinceIdle) {
10978                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10979                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10980                        if (doKilling && proc.initialIdlePss != 0
10981                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10982                            sb = new StringBuilder(128);
10983                            sb.append("Kill");
10984                            sb.append(proc.processName);
10985                            sb.append(" in idle maint: pss=");
10986                            sb.append(proc.lastPss);
10987                            sb.append(", initialPss=");
10988                            sb.append(proc.initialIdlePss);
10989                            sb.append(", period=");
10990                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10991                            sb.append(", lowRamPeriod=");
10992                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10993                            Slog.wtfQuiet(TAG, sb.toString());
10994                            proc.kill("idle maint (pss " + proc.lastPss
10995                                    + " from " + proc.initialIdlePss + ")", true);
10996                        }
10997                    }
10998                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10999                    proc.notCachedSinceIdle = true;
11000                    proc.initialIdlePss = 0;
11001                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11002                            mTestPssMode, isSleeping(), now);
11003                }
11004            }
11005
11006            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11007            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11008        }
11009    }
11010
11011    private void retrieveSettings() {
11012        final ContentResolver resolver = mContext.getContentResolver();
11013        String debugApp = Settings.Global.getString(
11014            resolver, Settings.Global.DEBUG_APP);
11015        boolean waitForDebugger = Settings.Global.getInt(
11016            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11017        boolean alwaysFinishActivities = Settings.Global.getInt(
11018            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11019        boolean forceRtl = Settings.Global.getInt(
11020                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11021        // Transfer any global setting for forcing RTL layout, into a System Property
11022        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11023
11024        Configuration configuration = new Configuration();
11025        Settings.System.getConfiguration(resolver, configuration);
11026        if (forceRtl) {
11027            // This will take care of setting the correct layout direction flags
11028            configuration.setLayoutDirection(configuration.locale);
11029        }
11030
11031        synchronized (this) {
11032            mDebugApp = mOrigDebugApp = debugApp;
11033            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11034            mAlwaysFinishActivities = alwaysFinishActivities;
11035            // This happens before any activities are started, so we can
11036            // change mConfiguration in-place.
11037            updateConfigurationLocked(configuration, null, false, true);
11038            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11039        }
11040    }
11041
11042    /** Loads resources after the current configuration has been set. */
11043    private void loadResourcesOnSystemReady() {
11044        final Resources res = mContext.getResources();
11045        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11046        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11047        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11048    }
11049
11050    public boolean testIsSystemReady() {
11051        // no need to synchronize(this) just to read & return the value
11052        return mSystemReady;
11053    }
11054
11055    private static File getCalledPreBootReceiversFile() {
11056        File dataDir = Environment.getDataDirectory();
11057        File systemDir = new File(dataDir, "system");
11058        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11059        return fname;
11060    }
11061
11062    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11063        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11064        File file = getCalledPreBootReceiversFile();
11065        FileInputStream fis = null;
11066        try {
11067            fis = new FileInputStream(file);
11068            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11069            int fvers = dis.readInt();
11070            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11071                String vers = dis.readUTF();
11072                String codename = dis.readUTF();
11073                String build = dis.readUTF();
11074                if (android.os.Build.VERSION.RELEASE.equals(vers)
11075                        && android.os.Build.VERSION.CODENAME.equals(codename)
11076                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11077                    int num = dis.readInt();
11078                    while (num > 0) {
11079                        num--;
11080                        String pkg = dis.readUTF();
11081                        String cls = dis.readUTF();
11082                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11083                    }
11084                }
11085            }
11086        } catch (FileNotFoundException e) {
11087        } catch (IOException e) {
11088            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11089        } finally {
11090            if (fis != null) {
11091                try {
11092                    fis.close();
11093                } catch (IOException e) {
11094                }
11095            }
11096        }
11097        return lastDoneReceivers;
11098    }
11099
11100    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11101        File file = getCalledPreBootReceiversFile();
11102        FileOutputStream fos = null;
11103        DataOutputStream dos = null;
11104        try {
11105            fos = new FileOutputStream(file);
11106            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11107            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11108            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11109            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11110            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11111            dos.writeInt(list.size());
11112            for (int i=0; i<list.size(); i++) {
11113                dos.writeUTF(list.get(i).getPackageName());
11114                dos.writeUTF(list.get(i).getClassName());
11115            }
11116        } catch (IOException e) {
11117            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11118            file.delete();
11119        } finally {
11120            FileUtils.sync(fos);
11121            if (dos != null) {
11122                try {
11123                    dos.close();
11124                } catch (IOException e) {
11125                    // TODO Auto-generated catch block
11126                    e.printStackTrace();
11127                }
11128            }
11129        }
11130    }
11131
11132    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11133            ArrayList<ComponentName> doneReceivers, int userId) {
11134        boolean waitingUpdate = false;
11135        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11136        List<ResolveInfo> ris = null;
11137        try {
11138            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11139                    intent, null, 0, userId);
11140        } catch (RemoteException e) {
11141        }
11142        if (ris != null) {
11143            for (int i=ris.size()-1; i>=0; i--) {
11144                if ((ris.get(i).activityInfo.applicationInfo.flags
11145                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11146                    ris.remove(i);
11147                }
11148            }
11149            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11150
11151            // For User 0, load the version number. When delivering to a new user, deliver
11152            // to all receivers.
11153            if (userId == UserHandle.USER_OWNER) {
11154                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11155                for (int i=0; i<ris.size(); i++) {
11156                    ActivityInfo ai = ris.get(i).activityInfo;
11157                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11158                    if (lastDoneReceivers.contains(comp)) {
11159                        // We already did the pre boot receiver for this app with the current
11160                        // platform version, so don't do it again...
11161                        ris.remove(i);
11162                        i--;
11163                        // ...however, do keep it as one that has been done, so we don't
11164                        // forget about it when rewriting the file of last done receivers.
11165                        doneReceivers.add(comp);
11166                    }
11167                }
11168            }
11169
11170            // If primary user, send broadcast to all available users, else just to userId
11171            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11172                    : new int[] { userId };
11173            for (int i = 0; i < ris.size(); i++) {
11174                ActivityInfo ai = ris.get(i).activityInfo;
11175                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11176                doneReceivers.add(comp);
11177                intent.setComponent(comp);
11178                for (int j=0; j<users.length; j++) {
11179                    IIntentReceiver finisher = null;
11180                    // On last receiver and user, set up a completion callback
11181                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11182                        finisher = new IIntentReceiver.Stub() {
11183                            public void performReceive(Intent intent, int resultCode,
11184                                    String data, Bundle extras, boolean ordered,
11185                                    boolean sticky, int sendingUser) {
11186                                // The raw IIntentReceiver interface is called
11187                                // with the AM lock held, so redispatch to
11188                                // execute our code without the lock.
11189                                mHandler.post(onFinishCallback);
11190                            }
11191                        };
11192                    }
11193                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11194                            + " for user " + users[j]);
11195                    broadcastIntentLocked(null, null, intent, null, finisher,
11196                            0, null, null, null, AppOpsManager.OP_NONE,
11197                            true, false, MY_PID, Process.SYSTEM_UID,
11198                            users[j]);
11199                    if (finisher != null) {
11200                        waitingUpdate = true;
11201                    }
11202                }
11203            }
11204        }
11205
11206        return waitingUpdate;
11207    }
11208
11209    public void systemReady(final Runnable goingCallback) {
11210        synchronized(this) {
11211            if (mSystemReady) {
11212                // If we're done calling all the receivers, run the next "boot phase" passed in
11213                // by the SystemServer
11214                if (goingCallback != null) {
11215                    goingCallback.run();
11216                }
11217                return;
11218            }
11219
11220            // Make sure we have the current profile info, since it is needed for
11221            // security checks.
11222            updateCurrentProfileIdsLocked();
11223
11224            if (mRecentTasks == null) {
11225                mRecentTasks = mTaskPersister.restoreTasksLocked();
11226                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11227                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11228                mTaskPersister.startPersisting();
11229            }
11230
11231            // Check to see if there are any update receivers to run.
11232            if (!mDidUpdate) {
11233                if (mWaitingUpdate) {
11234                    return;
11235                }
11236                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11237                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11238                    public void run() {
11239                        synchronized (ActivityManagerService.this) {
11240                            mDidUpdate = true;
11241                        }
11242                        writeLastDonePreBootReceivers(doneReceivers);
11243                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11244                                false);
11245                        systemReady(goingCallback);
11246                    }
11247                }, doneReceivers, UserHandle.USER_OWNER);
11248
11249                if (mWaitingUpdate) {
11250                    return;
11251                }
11252                mDidUpdate = true;
11253            }
11254
11255            mAppOpsService.systemReady();
11256            mSystemReady = true;
11257        }
11258
11259        ArrayList<ProcessRecord> procsToKill = null;
11260        synchronized(mPidsSelfLocked) {
11261            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11262                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11263                if (!isAllowedWhileBooting(proc.info)){
11264                    if (procsToKill == null) {
11265                        procsToKill = new ArrayList<ProcessRecord>();
11266                    }
11267                    procsToKill.add(proc);
11268                }
11269            }
11270        }
11271
11272        synchronized(this) {
11273            if (procsToKill != null) {
11274                for (int i=procsToKill.size()-1; i>=0; i--) {
11275                    ProcessRecord proc = procsToKill.get(i);
11276                    Slog.i(TAG, "Removing system update proc: " + proc);
11277                    removeProcessLocked(proc, true, false, "system update done");
11278                }
11279            }
11280
11281            // Now that we have cleaned up any update processes, we
11282            // are ready to start launching real processes and know that
11283            // we won't trample on them any more.
11284            mProcessesReady = true;
11285        }
11286
11287        Slog.i(TAG, "System now ready");
11288        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11289            SystemClock.uptimeMillis());
11290
11291        synchronized(this) {
11292            // Make sure we have no pre-ready processes sitting around.
11293
11294            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11295                ResolveInfo ri = mContext.getPackageManager()
11296                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11297                                STOCK_PM_FLAGS);
11298                CharSequence errorMsg = null;
11299                if (ri != null) {
11300                    ActivityInfo ai = ri.activityInfo;
11301                    ApplicationInfo app = ai.applicationInfo;
11302                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11303                        mTopAction = Intent.ACTION_FACTORY_TEST;
11304                        mTopData = null;
11305                        mTopComponent = new ComponentName(app.packageName,
11306                                ai.name);
11307                    } else {
11308                        errorMsg = mContext.getResources().getText(
11309                                com.android.internal.R.string.factorytest_not_system);
11310                    }
11311                } else {
11312                    errorMsg = mContext.getResources().getText(
11313                            com.android.internal.R.string.factorytest_no_action);
11314                }
11315                if (errorMsg != null) {
11316                    mTopAction = null;
11317                    mTopData = null;
11318                    mTopComponent = null;
11319                    Message msg = Message.obtain();
11320                    msg.what = SHOW_FACTORY_ERROR_MSG;
11321                    msg.getData().putCharSequence("msg", errorMsg);
11322                    mHandler.sendMessage(msg);
11323                }
11324            }
11325        }
11326
11327        retrieveSettings();
11328        loadResourcesOnSystemReady();
11329
11330        synchronized (this) {
11331            readGrantedUriPermissionsLocked();
11332        }
11333
11334        if (goingCallback != null) goingCallback.run();
11335
11336        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11337                Integer.toString(mCurrentUserId), mCurrentUserId);
11338        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11339                Integer.toString(mCurrentUserId), mCurrentUserId);
11340        mSystemServiceManager.startUser(mCurrentUserId);
11341
11342        synchronized (this) {
11343            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11344                try {
11345                    List apps = AppGlobals.getPackageManager().
11346                        getPersistentApplications(STOCK_PM_FLAGS);
11347                    if (apps != null) {
11348                        int N = apps.size();
11349                        int i;
11350                        for (i=0; i<N; i++) {
11351                            ApplicationInfo info
11352                                = (ApplicationInfo)apps.get(i);
11353                            if (info != null &&
11354                                    !info.packageName.equals("android")) {
11355                                addAppLocked(info, false, null /* ABI override */);
11356                            }
11357                        }
11358                    }
11359                } catch (RemoteException ex) {
11360                    // pm is in same process, this will never happen.
11361                }
11362            }
11363
11364            // Start up initial activity.
11365            mBooting = true;
11366            startHomeActivityLocked(mCurrentUserId, "systemReady");
11367
11368            try {
11369                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11370                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11371                            + " data partition or your device will be unstable.");
11372                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11373                }
11374            } catch (RemoteException e) {
11375            }
11376
11377            if (!Build.isFingerprintConsistent()) {
11378                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11379                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11380            }
11381
11382            long ident = Binder.clearCallingIdentity();
11383            try {
11384                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11385                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11386                        | Intent.FLAG_RECEIVER_FOREGROUND);
11387                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11388                broadcastIntentLocked(null, null, intent,
11389                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11390                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11391                intent = new Intent(Intent.ACTION_USER_STARTING);
11392                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11393                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11394                broadcastIntentLocked(null, null, intent,
11395                        null, new IIntentReceiver.Stub() {
11396                            @Override
11397                            public void performReceive(Intent intent, int resultCode, String data,
11398                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11399                                    throws RemoteException {
11400                            }
11401                        }, 0, null, null,
11402                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11403                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11404            } catch (Throwable t) {
11405                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11406            } finally {
11407                Binder.restoreCallingIdentity(ident);
11408            }
11409            mStackSupervisor.resumeTopActivitiesLocked();
11410            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11411        }
11412    }
11413
11414    private boolean makeAppCrashingLocked(ProcessRecord app,
11415            String shortMsg, String longMsg, String stackTrace) {
11416        app.crashing = true;
11417        app.crashingReport = generateProcessError(app,
11418                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11419        startAppProblemLocked(app);
11420        app.stopFreezingAllLocked();
11421        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11422    }
11423
11424    private void makeAppNotRespondingLocked(ProcessRecord app,
11425            String activity, String shortMsg, String longMsg) {
11426        app.notResponding = true;
11427        app.notRespondingReport = generateProcessError(app,
11428                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11429                activity, shortMsg, longMsg, null);
11430        startAppProblemLocked(app);
11431        app.stopFreezingAllLocked();
11432    }
11433
11434    /**
11435     * Generate a process error record, suitable for attachment to a ProcessRecord.
11436     *
11437     * @param app The ProcessRecord in which the error occurred.
11438     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11439     *                      ActivityManager.AppErrorStateInfo
11440     * @param activity The activity associated with the crash, if known.
11441     * @param shortMsg Short message describing the crash.
11442     * @param longMsg Long message describing the crash.
11443     * @param stackTrace Full crash stack trace, may be null.
11444     *
11445     * @return Returns a fully-formed AppErrorStateInfo record.
11446     */
11447    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11448            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11449        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11450
11451        report.condition = condition;
11452        report.processName = app.processName;
11453        report.pid = app.pid;
11454        report.uid = app.info.uid;
11455        report.tag = activity;
11456        report.shortMsg = shortMsg;
11457        report.longMsg = longMsg;
11458        report.stackTrace = stackTrace;
11459
11460        return report;
11461    }
11462
11463    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11464        synchronized (this) {
11465            app.crashing = false;
11466            app.crashingReport = null;
11467            app.notResponding = false;
11468            app.notRespondingReport = null;
11469            if (app.anrDialog == fromDialog) {
11470                app.anrDialog = null;
11471            }
11472            if (app.waitDialog == fromDialog) {
11473                app.waitDialog = null;
11474            }
11475            if (app.pid > 0 && app.pid != MY_PID) {
11476                handleAppCrashLocked(app, null, null, null);
11477                app.kill("user request after error", true);
11478            }
11479        }
11480    }
11481
11482    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11483            String stackTrace) {
11484        long now = SystemClock.uptimeMillis();
11485
11486        Long crashTime;
11487        if (!app.isolated) {
11488            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11489        } else {
11490            crashTime = null;
11491        }
11492        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11493            // This process loses!
11494            Slog.w(TAG, "Process " + app.info.processName
11495                    + " has crashed too many times: killing!");
11496            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11497                    app.userId, app.info.processName, app.uid);
11498            mStackSupervisor.handleAppCrashLocked(app);
11499            if (!app.persistent) {
11500                // We don't want to start this process again until the user
11501                // explicitly does so...  but for persistent process, we really
11502                // need to keep it running.  If a persistent process is actually
11503                // repeatedly crashing, then badness for everyone.
11504                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11505                        app.info.processName);
11506                if (!app.isolated) {
11507                    // XXX We don't have a way to mark isolated processes
11508                    // as bad, since they don't have a peristent identity.
11509                    mBadProcesses.put(app.info.processName, app.uid,
11510                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11511                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11512                }
11513                app.bad = true;
11514                app.removed = true;
11515                // Don't let services in this process be restarted and potentially
11516                // annoy the user repeatedly.  Unless it is persistent, since those
11517                // processes run critical code.
11518                removeProcessLocked(app, false, false, "crash");
11519                mStackSupervisor.resumeTopActivitiesLocked();
11520                return false;
11521            }
11522            mStackSupervisor.resumeTopActivitiesLocked();
11523        } else {
11524            mStackSupervisor.finishTopRunningActivityLocked(app);
11525        }
11526
11527        // Bump up the crash count of any services currently running in the proc.
11528        for (int i=app.services.size()-1; i>=0; i--) {
11529            // Any services running in the application need to be placed
11530            // back in the pending list.
11531            ServiceRecord sr = app.services.valueAt(i);
11532            sr.crashCount++;
11533        }
11534
11535        // If the crashing process is what we consider to be the "home process" and it has been
11536        // replaced by a third-party app, clear the package preferred activities from packages
11537        // with a home activity running in the process to prevent a repeatedly crashing app
11538        // from blocking the user to manually clear the list.
11539        final ArrayList<ActivityRecord> activities = app.activities;
11540        if (app == mHomeProcess && activities.size() > 0
11541                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11542            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11543                final ActivityRecord r = activities.get(activityNdx);
11544                if (r.isHomeActivity()) {
11545                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11546                    try {
11547                        ActivityThread.getPackageManager()
11548                                .clearPackagePreferredActivities(r.packageName);
11549                    } catch (RemoteException c) {
11550                        // pm is in same process, this will never happen.
11551                    }
11552                }
11553            }
11554        }
11555
11556        if (!app.isolated) {
11557            // XXX Can't keep track of crash times for isolated processes,
11558            // because they don't have a perisistent identity.
11559            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11560        }
11561
11562        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11563        return true;
11564    }
11565
11566    void startAppProblemLocked(ProcessRecord app) {
11567        // If this app is not running under the current user, then we
11568        // can't give it a report button because that would require
11569        // launching the report UI under a different user.
11570        app.errorReportReceiver = null;
11571
11572        for (int userId : mCurrentProfileIds) {
11573            if (app.userId == userId) {
11574                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11575                        mContext, app.info.packageName, app.info.flags);
11576            }
11577        }
11578        skipCurrentReceiverLocked(app);
11579    }
11580
11581    void skipCurrentReceiverLocked(ProcessRecord app) {
11582        for (BroadcastQueue queue : mBroadcastQueues) {
11583            queue.skipCurrentReceiverLocked(app);
11584        }
11585    }
11586
11587    /**
11588     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11589     * The application process will exit immediately after this call returns.
11590     * @param app object of the crashing app, null for the system server
11591     * @param crashInfo describing the exception
11592     */
11593    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11594        ProcessRecord r = findAppProcess(app, "Crash");
11595        final String processName = app == null ? "system_server"
11596                : (r == null ? "unknown" : r.processName);
11597
11598        handleApplicationCrashInner("crash", r, processName, crashInfo);
11599    }
11600
11601    /* Native crash reporting uses this inner version because it needs to be somewhat
11602     * decoupled from the AM-managed cleanup lifecycle
11603     */
11604    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11605            ApplicationErrorReport.CrashInfo crashInfo) {
11606        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11607                UserHandle.getUserId(Binder.getCallingUid()), processName,
11608                r == null ? -1 : r.info.flags,
11609                crashInfo.exceptionClassName,
11610                crashInfo.exceptionMessage,
11611                crashInfo.throwFileName,
11612                crashInfo.throwLineNumber);
11613
11614        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11615
11616        crashApplication(r, crashInfo);
11617    }
11618
11619    public void handleApplicationStrictModeViolation(
11620            IBinder app,
11621            int violationMask,
11622            StrictMode.ViolationInfo info) {
11623        ProcessRecord r = findAppProcess(app, "StrictMode");
11624        if (r == null) {
11625            return;
11626        }
11627
11628        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11629            Integer stackFingerprint = info.hashCode();
11630            boolean logIt = true;
11631            synchronized (mAlreadyLoggedViolatedStacks) {
11632                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11633                    logIt = false;
11634                    // TODO: sub-sample into EventLog for these, with
11635                    // the info.durationMillis?  Then we'd get
11636                    // the relative pain numbers, without logging all
11637                    // the stack traces repeatedly.  We'd want to do
11638                    // likewise in the client code, which also does
11639                    // dup suppression, before the Binder call.
11640                } else {
11641                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11642                        mAlreadyLoggedViolatedStacks.clear();
11643                    }
11644                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11645                }
11646            }
11647            if (logIt) {
11648                logStrictModeViolationToDropBox(r, info);
11649            }
11650        }
11651
11652        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11653            AppErrorResult result = new AppErrorResult();
11654            synchronized (this) {
11655                final long origId = Binder.clearCallingIdentity();
11656
11657                Message msg = Message.obtain();
11658                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11659                HashMap<String, Object> data = new HashMap<String, Object>();
11660                data.put("result", result);
11661                data.put("app", r);
11662                data.put("violationMask", violationMask);
11663                data.put("info", info);
11664                msg.obj = data;
11665                mHandler.sendMessage(msg);
11666
11667                Binder.restoreCallingIdentity(origId);
11668            }
11669            int res = result.get();
11670            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11671        }
11672    }
11673
11674    // Depending on the policy in effect, there could be a bunch of
11675    // these in quick succession so we try to batch these together to
11676    // minimize disk writes, number of dropbox entries, and maximize
11677    // compression, by having more fewer, larger records.
11678    private void logStrictModeViolationToDropBox(
11679            ProcessRecord process,
11680            StrictMode.ViolationInfo info) {
11681        if (info == null) {
11682            return;
11683        }
11684        final boolean isSystemApp = process == null ||
11685                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11686                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11687        final String processName = process == null ? "unknown" : process.processName;
11688        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11689        final DropBoxManager dbox = (DropBoxManager)
11690                mContext.getSystemService(Context.DROPBOX_SERVICE);
11691
11692        // Exit early if the dropbox isn't configured to accept this report type.
11693        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11694
11695        boolean bufferWasEmpty;
11696        boolean needsFlush;
11697        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11698        synchronized (sb) {
11699            bufferWasEmpty = sb.length() == 0;
11700            appendDropBoxProcessHeaders(process, processName, sb);
11701            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11702            sb.append("System-App: ").append(isSystemApp).append("\n");
11703            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11704            if (info.violationNumThisLoop != 0) {
11705                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11706            }
11707            if (info.numAnimationsRunning != 0) {
11708                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11709            }
11710            if (info.broadcastIntentAction != null) {
11711                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11712            }
11713            if (info.durationMillis != -1) {
11714                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11715            }
11716            if (info.numInstances != -1) {
11717                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11718            }
11719            if (info.tags != null) {
11720                for (String tag : info.tags) {
11721                    sb.append("Span-Tag: ").append(tag).append("\n");
11722                }
11723            }
11724            sb.append("\n");
11725            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11726                sb.append(info.crashInfo.stackTrace);
11727                sb.append("\n");
11728            }
11729            if (info.message != null) {
11730                sb.append(info.message);
11731                sb.append("\n");
11732            }
11733
11734            // Only buffer up to ~64k.  Various logging bits truncate
11735            // things at 128k.
11736            needsFlush = (sb.length() > 64 * 1024);
11737        }
11738
11739        // Flush immediately if the buffer's grown too large, or this
11740        // is a non-system app.  Non-system apps are isolated with a
11741        // different tag & policy and not batched.
11742        //
11743        // Batching is useful during internal testing with
11744        // StrictMode settings turned up high.  Without batching,
11745        // thousands of separate files could be created on boot.
11746        if (!isSystemApp || needsFlush) {
11747            new Thread("Error dump: " + dropboxTag) {
11748                @Override
11749                public void run() {
11750                    String report;
11751                    synchronized (sb) {
11752                        report = sb.toString();
11753                        sb.delete(0, sb.length());
11754                        sb.trimToSize();
11755                    }
11756                    if (report.length() != 0) {
11757                        dbox.addText(dropboxTag, report);
11758                    }
11759                }
11760            }.start();
11761            return;
11762        }
11763
11764        // System app batching:
11765        if (!bufferWasEmpty) {
11766            // An existing dropbox-writing thread is outstanding, so
11767            // we don't need to start it up.  The existing thread will
11768            // catch the buffer appends we just did.
11769            return;
11770        }
11771
11772        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11773        // (After this point, we shouldn't access AMS internal data structures.)
11774        new Thread("Error dump: " + dropboxTag) {
11775            @Override
11776            public void run() {
11777                // 5 second sleep to let stacks arrive and be batched together
11778                try {
11779                    Thread.sleep(5000);  // 5 seconds
11780                } catch (InterruptedException e) {}
11781
11782                String errorReport;
11783                synchronized (mStrictModeBuffer) {
11784                    errorReport = mStrictModeBuffer.toString();
11785                    if (errorReport.length() == 0) {
11786                        return;
11787                    }
11788                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11789                    mStrictModeBuffer.trimToSize();
11790                }
11791                dbox.addText(dropboxTag, errorReport);
11792            }
11793        }.start();
11794    }
11795
11796    /**
11797     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11798     * @param app object of the crashing app, null for the system server
11799     * @param tag reported by the caller
11800     * @param system whether this wtf is coming from the system
11801     * @param crashInfo describing the context of the error
11802     * @return true if the process should exit immediately (WTF is fatal)
11803     */
11804    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11805            final ApplicationErrorReport.CrashInfo crashInfo) {
11806        final int callingUid = Binder.getCallingUid();
11807        final int callingPid = Binder.getCallingPid();
11808
11809        if (system) {
11810            // If this is coming from the system, we could very well have low-level
11811            // system locks held, so we want to do this all asynchronously.  And we
11812            // never want this to become fatal, so there is that too.
11813            mHandler.post(new Runnable() {
11814                @Override public void run() {
11815                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11816                }
11817            });
11818            return false;
11819        }
11820
11821        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11822                crashInfo);
11823
11824        if (r != null && r.pid != Process.myPid() &&
11825                Settings.Global.getInt(mContext.getContentResolver(),
11826                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11827            crashApplication(r, crashInfo);
11828            return true;
11829        } else {
11830            return false;
11831        }
11832    }
11833
11834    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11835            final ApplicationErrorReport.CrashInfo crashInfo) {
11836        final ProcessRecord r = findAppProcess(app, "WTF");
11837        final String processName = app == null ? "system_server"
11838                : (r == null ? "unknown" : r.processName);
11839
11840        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11841                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11842
11843        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11844
11845        return r;
11846    }
11847
11848    /**
11849     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11850     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11851     */
11852    private ProcessRecord findAppProcess(IBinder app, String reason) {
11853        if (app == null) {
11854            return null;
11855        }
11856
11857        synchronized (this) {
11858            final int NP = mProcessNames.getMap().size();
11859            for (int ip=0; ip<NP; ip++) {
11860                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11861                final int NA = apps.size();
11862                for (int ia=0; ia<NA; ia++) {
11863                    ProcessRecord p = apps.valueAt(ia);
11864                    if (p.thread != null && p.thread.asBinder() == app) {
11865                        return p;
11866                    }
11867                }
11868            }
11869
11870            Slog.w(TAG, "Can't find mystery application for " + reason
11871                    + " from pid=" + Binder.getCallingPid()
11872                    + " uid=" + Binder.getCallingUid() + ": " + app);
11873            return null;
11874        }
11875    }
11876
11877    /**
11878     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11879     * to append various headers to the dropbox log text.
11880     */
11881    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11882            StringBuilder sb) {
11883        // Watchdog thread ends up invoking this function (with
11884        // a null ProcessRecord) to add the stack file to dropbox.
11885        // Do not acquire a lock on this (am) in such cases, as it
11886        // could cause a potential deadlock, if and when watchdog
11887        // is invoked due to unavailability of lock on am and it
11888        // would prevent watchdog from killing system_server.
11889        if (process == null) {
11890            sb.append("Process: ").append(processName).append("\n");
11891            return;
11892        }
11893        // Note: ProcessRecord 'process' is guarded by the service
11894        // instance.  (notably process.pkgList, which could otherwise change
11895        // concurrently during execution of this method)
11896        synchronized (this) {
11897            sb.append("Process: ").append(processName).append("\n");
11898            int flags = process.info.flags;
11899            IPackageManager pm = AppGlobals.getPackageManager();
11900            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11901            for (int ip=0; ip<process.pkgList.size(); ip++) {
11902                String pkg = process.pkgList.keyAt(ip);
11903                sb.append("Package: ").append(pkg);
11904                try {
11905                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11906                    if (pi != null) {
11907                        sb.append(" v").append(pi.versionCode);
11908                        if (pi.versionName != null) {
11909                            sb.append(" (").append(pi.versionName).append(")");
11910                        }
11911                    }
11912                } catch (RemoteException e) {
11913                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11914                }
11915                sb.append("\n");
11916            }
11917        }
11918    }
11919
11920    private static String processClass(ProcessRecord process) {
11921        if (process == null || process.pid == MY_PID) {
11922            return "system_server";
11923        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11924            return "system_app";
11925        } else {
11926            return "data_app";
11927        }
11928    }
11929
11930    /**
11931     * Write a description of an error (crash, WTF, ANR) to the drop box.
11932     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11933     * @param process which caused the error, null means the system server
11934     * @param activity which triggered the error, null if unknown
11935     * @param parent activity related to the error, null if unknown
11936     * @param subject line related to the error, null if absent
11937     * @param report in long form describing the error, null if absent
11938     * @param logFile to include in the report, null if none
11939     * @param crashInfo giving an application stack trace, null if absent
11940     */
11941    public void addErrorToDropBox(String eventType,
11942            ProcessRecord process, String processName, ActivityRecord activity,
11943            ActivityRecord parent, String subject,
11944            final String report, final File logFile,
11945            final ApplicationErrorReport.CrashInfo crashInfo) {
11946        // NOTE -- this must never acquire the ActivityManagerService lock,
11947        // otherwise the watchdog may be prevented from resetting the system.
11948
11949        final String dropboxTag = processClass(process) + "_" + eventType;
11950        final DropBoxManager dbox = (DropBoxManager)
11951                mContext.getSystemService(Context.DROPBOX_SERVICE);
11952
11953        // Exit early if the dropbox isn't configured to accept this report type.
11954        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11955
11956        final StringBuilder sb = new StringBuilder(1024);
11957        appendDropBoxProcessHeaders(process, processName, sb);
11958        if (activity != null) {
11959            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11960        }
11961        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11962            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11963        }
11964        if (parent != null && parent != activity) {
11965            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11966        }
11967        if (subject != null) {
11968            sb.append("Subject: ").append(subject).append("\n");
11969        }
11970        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11971        if (Debug.isDebuggerConnected()) {
11972            sb.append("Debugger: Connected\n");
11973        }
11974        sb.append("\n");
11975
11976        // Do the rest in a worker thread to avoid blocking the caller on I/O
11977        // (After this point, we shouldn't access AMS internal data structures.)
11978        Thread worker = new Thread("Error dump: " + dropboxTag) {
11979            @Override
11980            public void run() {
11981                if (report != null) {
11982                    sb.append(report);
11983                }
11984                if (logFile != null) {
11985                    try {
11986                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11987                                    "\n\n[[TRUNCATED]]"));
11988                    } catch (IOException e) {
11989                        Slog.e(TAG, "Error reading " + logFile, e);
11990                    }
11991                }
11992                if (crashInfo != null && crashInfo.stackTrace != null) {
11993                    sb.append(crashInfo.stackTrace);
11994                }
11995
11996                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11997                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11998                if (lines > 0) {
11999                    sb.append("\n");
12000
12001                    // Merge several logcat streams, and take the last N lines
12002                    InputStreamReader input = null;
12003                    try {
12004                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12005                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12006                                "-b", "crash",
12007                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12008
12009                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12010                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12011                        input = new InputStreamReader(logcat.getInputStream());
12012
12013                        int num;
12014                        char[] buf = new char[8192];
12015                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12016                    } catch (IOException e) {
12017                        Slog.e(TAG, "Error running logcat", e);
12018                    } finally {
12019                        if (input != null) try { input.close(); } catch (IOException e) {}
12020                    }
12021                }
12022
12023                dbox.addText(dropboxTag, sb.toString());
12024            }
12025        };
12026
12027        if (process == null) {
12028            // If process is null, we are being called from some internal code
12029            // and may be about to die -- run this synchronously.
12030            worker.run();
12031        } else {
12032            worker.start();
12033        }
12034    }
12035
12036    /**
12037     * Bring up the "unexpected error" dialog box for a crashing app.
12038     * Deal with edge cases (intercepts from instrumented applications,
12039     * ActivityController, error intent receivers, that sort of thing).
12040     * @param r the application crashing
12041     * @param crashInfo describing the failure
12042     */
12043    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12044        long timeMillis = System.currentTimeMillis();
12045        String shortMsg = crashInfo.exceptionClassName;
12046        String longMsg = crashInfo.exceptionMessage;
12047        String stackTrace = crashInfo.stackTrace;
12048        if (shortMsg != null && longMsg != null) {
12049            longMsg = shortMsg + ": " + longMsg;
12050        } else if (shortMsg != null) {
12051            longMsg = shortMsg;
12052        }
12053
12054        AppErrorResult result = new AppErrorResult();
12055        synchronized (this) {
12056            if (mController != null) {
12057                try {
12058                    String name = r != null ? r.processName : null;
12059                    int pid = r != null ? r.pid : Binder.getCallingPid();
12060                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12061                    if (!mController.appCrashed(name, pid,
12062                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12063                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12064                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12065                            Slog.w(TAG, "Skip killing native crashed app " + name
12066                                    + "(" + pid + ") during testing");
12067                        } else {
12068                            Slog.w(TAG, "Force-killing crashed app " + name
12069                                    + " at watcher's request");
12070                            if (r != null) {
12071                                r.kill("crash", true);
12072                            } else {
12073                                // Huh.
12074                                Process.killProcess(pid);
12075                                Process.killProcessGroup(uid, pid);
12076                            }
12077                        }
12078                        return;
12079                    }
12080                } catch (RemoteException e) {
12081                    mController = null;
12082                    Watchdog.getInstance().setActivityController(null);
12083                }
12084            }
12085
12086            final long origId = Binder.clearCallingIdentity();
12087
12088            // If this process is running instrumentation, finish it.
12089            if (r != null && r.instrumentationClass != null) {
12090                Slog.w(TAG, "Error in app " + r.processName
12091                      + " running instrumentation " + r.instrumentationClass + ":");
12092                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12093                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12094                Bundle info = new Bundle();
12095                info.putString("shortMsg", shortMsg);
12096                info.putString("longMsg", longMsg);
12097                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12098                Binder.restoreCallingIdentity(origId);
12099                return;
12100            }
12101
12102            // Log crash in battery stats.
12103            if (r != null) {
12104                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12105            }
12106
12107            // If we can't identify the process or it's already exceeded its crash quota,
12108            // quit right away without showing a crash dialog.
12109            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12110                Binder.restoreCallingIdentity(origId);
12111                return;
12112            }
12113
12114            Message msg = Message.obtain();
12115            msg.what = SHOW_ERROR_MSG;
12116            HashMap data = new HashMap();
12117            data.put("result", result);
12118            data.put("app", r);
12119            msg.obj = data;
12120            mHandler.sendMessage(msg);
12121
12122            Binder.restoreCallingIdentity(origId);
12123        }
12124
12125        int res = result.get();
12126
12127        Intent appErrorIntent = null;
12128        synchronized (this) {
12129            if (r != null && !r.isolated) {
12130                // XXX Can't keep track of crash time for isolated processes,
12131                // since they don't have a persistent identity.
12132                mProcessCrashTimes.put(r.info.processName, r.uid,
12133                        SystemClock.uptimeMillis());
12134            }
12135            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12136                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12137            }
12138        }
12139
12140        if (appErrorIntent != null) {
12141            try {
12142                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12143            } catch (ActivityNotFoundException e) {
12144                Slog.w(TAG, "bug report receiver dissappeared", e);
12145            }
12146        }
12147    }
12148
12149    Intent createAppErrorIntentLocked(ProcessRecord r,
12150            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12151        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12152        if (report == null) {
12153            return null;
12154        }
12155        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12156        result.setComponent(r.errorReportReceiver);
12157        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12158        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12159        return result;
12160    }
12161
12162    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12163            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12164        if (r.errorReportReceiver == null) {
12165            return null;
12166        }
12167
12168        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12169            return null;
12170        }
12171
12172        ApplicationErrorReport report = new ApplicationErrorReport();
12173        report.packageName = r.info.packageName;
12174        report.installerPackageName = r.errorReportReceiver.getPackageName();
12175        report.processName = r.processName;
12176        report.time = timeMillis;
12177        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12178
12179        if (r.crashing || r.forceCrashReport) {
12180            report.type = ApplicationErrorReport.TYPE_CRASH;
12181            report.crashInfo = crashInfo;
12182        } else if (r.notResponding) {
12183            report.type = ApplicationErrorReport.TYPE_ANR;
12184            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12185
12186            report.anrInfo.activity = r.notRespondingReport.tag;
12187            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12188            report.anrInfo.info = r.notRespondingReport.longMsg;
12189        }
12190
12191        return report;
12192    }
12193
12194    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12195        enforceNotIsolatedCaller("getProcessesInErrorState");
12196        // assume our apps are happy - lazy create the list
12197        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12198
12199        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12200                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12201        int userId = UserHandle.getUserId(Binder.getCallingUid());
12202
12203        synchronized (this) {
12204
12205            // iterate across all processes
12206            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12207                ProcessRecord app = mLruProcesses.get(i);
12208                if (!allUsers && app.userId != userId) {
12209                    continue;
12210                }
12211                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12212                    // This one's in trouble, so we'll generate a report for it
12213                    // crashes are higher priority (in case there's a crash *and* an anr)
12214                    ActivityManager.ProcessErrorStateInfo report = null;
12215                    if (app.crashing) {
12216                        report = app.crashingReport;
12217                    } else if (app.notResponding) {
12218                        report = app.notRespondingReport;
12219                    }
12220
12221                    if (report != null) {
12222                        if (errList == null) {
12223                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12224                        }
12225                        errList.add(report);
12226                    } else {
12227                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12228                                " crashing = " + app.crashing +
12229                                " notResponding = " + app.notResponding);
12230                    }
12231                }
12232            }
12233        }
12234
12235        return errList;
12236    }
12237
12238    static int procStateToImportance(int procState, int memAdj,
12239            ActivityManager.RunningAppProcessInfo currApp) {
12240        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12241        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12242            currApp.lru = memAdj;
12243        } else {
12244            currApp.lru = 0;
12245        }
12246        return imp;
12247    }
12248
12249    private void fillInProcMemInfo(ProcessRecord app,
12250            ActivityManager.RunningAppProcessInfo outInfo) {
12251        outInfo.pid = app.pid;
12252        outInfo.uid = app.info.uid;
12253        if (mHeavyWeightProcess == app) {
12254            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12255        }
12256        if (app.persistent) {
12257            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12258        }
12259        if (app.activities.size() > 0) {
12260            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12261        }
12262        outInfo.lastTrimLevel = app.trimMemoryLevel;
12263        int adj = app.curAdj;
12264        int procState = app.curProcState;
12265        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12266        outInfo.importanceReasonCode = app.adjTypeCode;
12267        outInfo.processState = app.curProcState;
12268    }
12269
12270    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12271        enforceNotIsolatedCaller("getRunningAppProcesses");
12272        // Lazy instantiation of list
12273        List<ActivityManager.RunningAppProcessInfo> runList = null;
12274        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12275                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12276        int userId = UserHandle.getUserId(Binder.getCallingUid());
12277        synchronized (this) {
12278            // Iterate across all processes
12279            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12280                ProcessRecord app = mLruProcesses.get(i);
12281                if (!allUsers && app.userId != userId) {
12282                    continue;
12283                }
12284                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12285                    // Generate process state info for running application
12286                    ActivityManager.RunningAppProcessInfo currApp =
12287                        new ActivityManager.RunningAppProcessInfo(app.processName,
12288                                app.pid, app.getPackageList());
12289                    fillInProcMemInfo(app, currApp);
12290                    if (app.adjSource instanceof ProcessRecord) {
12291                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12292                        currApp.importanceReasonImportance =
12293                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12294                                        app.adjSourceProcState);
12295                    } else if (app.adjSource instanceof ActivityRecord) {
12296                        ActivityRecord r = (ActivityRecord)app.adjSource;
12297                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12298                    }
12299                    if (app.adjTarget instanceof ComponentName) {
12300                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12301                    }
12302                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12303                    //        + " lru=" + currApp.lru);
12304                    if (runList == null) {
12305                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12306                    }
12307                    runList.add(currApp);
12308                }
12309            }
12310        }
12311        return runList;
12312    }
12313
12314    public List<ApplicationInfo> getRunningExternalApplications() {
12315        enforceNotIsolatedCaller("getRunningExternalApplications");
12316        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12317        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12318        if (runningApps != null && runningApps.size() > 0) {
12319            Set<String> extList = new HashSet<String>();
12320            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12321                if (app.pkgList != null) {
12322                    for (String pkg : app.pkgList) {
12323                        extList.add(pkg);
12324                    }
12325                }
12326            }
12327            IPackageManager pm = AppGlobals.getPackageManager();
12328            for (String pkg : extList) {
12329                try {
12330                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12331                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12332                        retList.add(info);
12333                    }
12334                } catch (RemoteException e) {
12335                }
12336            }
12337        }
12338        return retList;
12339    }
12340
12341    @Override
12342    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12343        enforceNotIsolatedCaller("getMyMemoryState");
12344        synchronized (this) {
12345            ProcessRecord proc;
12346            synchronized (mPidsSelfLocked) {
12347                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12348            }
12349            fillInProcMemInfo(proc, outInfo);
12350        }
12351    }
12352
12353    @Override
12354    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12355        if (checkCallingPermission(android.Manifest.permission.DUMP)
12356                != PackageManager.PERMISSION_GRANTED) {
12357            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12358                    + Binder.getCallingPid()
12359                    + ", uid=" + Binder.getCallingUid()
12360                    + " without permission "
12361                    + android.Manifest.permission.DUMP);
12362            return;
12363        }
12364
12365        boolean dumpAll = false;
12366        boolean dumpClient = false;
12367        String dumpPackage = null;
12368
12369        int opti = 0;
12370        while (opti < args.length) {
12371            String opt = args[opti];
12372            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12373                break;
12374            }
12375            opti++;
12376            if ("-a".equals(opt)) {
12377                dumpAll = true;
12378            } else if ("-c".equals(opt)) {
12379                dumpClient = true;
12380            } else if ("-p".equals(opt)) {
12381                if (opti < args.length) {
12382                    dumpPackage = args[opti];
12383                    opti++;
12384                } else {
12385                    pw.println("Error: -p option requires package argument");
12386                    return;
12387                }
12388                dumpClient = true;
12389            } else if ("-h".equals(opt)) {
12390                pw.println("Activity manager dump options:");
12391                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12392                pw.println("  cmd may be one of:");
12393                pw.println("    a[ctivities]: activity stack state");
12394                pw.println("    r[recents]: recent activities state");
12395                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12396                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12397                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12398                pw.println("    o[om]: out of memory management");
12399                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12400                pw.println("    provider [COMP_SPEC]: provider client-side state");
12401                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12402                pw.println("    as[sociations]: tracked app associations");
12403                pw.println("    service [COMP_SPEC]: service client-side state");
12404                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12405                pw.println("    all: dump all activities");
12406                pw.println("    top: dump the top activity");
12407                pw.println("    write: write all pending state to storage");
12408                pw.println("    track-associations: enable association tracking");
12409                pw.println("    untrack-associations: disable and clear association tracking");
12410                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12411                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12412                pw.println("    a partial substring in a component name, a");
12413                pw.println("    hex object identifier.");
12414                pw.println("  -a: include all available server state.");
12415                pw.println("  -c: include client state.");
12416                pw.println("  -p: limit output to given package.");
12417                return;
12418            } else {
12419                pw.println("Unknown argument: " + opt + "; use -h for help");
12420            }
12421        }
12422
12423        long origId = Binder.clearCallingIdentity();
12424        boolean more = false;
12425        // Is the caller requesting to dump a particular piece of data?
12426        if (opti < args.length) {
12427            String cmd = args[opti];
12428            opti++;
12429            if ("activities".equals(cmd) || "a".equals(cmd)) {
12430                synchronized (this) {
12431                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12432                }
12433            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12434                synchronized (this) {
12435                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12436                }
12437            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12438                String[] newArgs;
12439                String name;
12440                if (opti >= args.length) {
12441                    name = null;
12442                    newArgs = EMPTY_STRING_ARRAY;
12443                } else {
12444                    dumpPackage = args[opti];
12445                    opti++;
12446                    newArgs = new String[args.length - opti];
12447                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12448                            args.length - opti);
12449                }
12450                synchronized (this) {
12451                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12452                }
12453            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12454                String[] newArgs;
12455                String name;
12456                if (opti >= args.length) {
12457                    name = null;
12458                    newArgs = EMPTY_STRING_ARRAY;
12459                } else {
12460                    dumpPackage = args[opti];
12461                    opti++;
12462                    newArgs = new String[args.length - opti];
12463                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12464                            args.length - opti);
12465                }
12466                synchronized (this) {
12467                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12468                }
12469            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12470                String[] newArgs;
12471                String name;
12472                if (opti >= args.length) {
12473                    name = null;
12474                    newArgs = EMPTY_STRING_ARRAY;
12475                } else {
12476                    dumpPackage = args[opti];
12477                    opti++;
12478                    newArgs = new String[args.length - opti];
12479                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12480                            args.length - opti);
12481                }
12482                synchronized (this) {
12483                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12484                }
12485            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12486                synchronized (this) {
12487                    dumpOomLocked(fd, pw, args, opti, true);
12488                }
12489            } else if ("provider".equals(cmd)) {
12490                String[] newArgs;
12491                String name;
12492                if (opti >= args.length) {
12493                    name = null;
12494                    newArgs = EMPTY_STRING_ARRAY;
12495                } else {
12496                    name = args[opti];
12497                    opti++;
12498                    newArgs = new String[args.length - opti];
12499                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12500                }
12501                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12502                    pw.println("No providers match: " + name);
12503                    pw.println("Use -h for help.");
12504                }
12505            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12506                synchronized (this) {
12507                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12508                }
12509            } else if ("service".equals(cmd)) {
12510                String[] newArgs;
12511                String name;
12512                if (opti >= args.length) {
12513                    name = null;
12514                    newArgs = EMPTY_STRING_ARRAY;
12515                } else {
12516                    name = args[opti];
12517                    opti++;
12518                    newArgs = new String[args.length - opti];
12519                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12520                            args.length - opti);
12521                }
12522                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12523                    pw.println("No services match: " + name);
12524                    pw.println("Use -h for help.");
12525                }
12526            } else if ("package".equals(cmd)) {
12527                String[] newArgs;
12528                if (opti >= args.length) {
12529                    pw.println("package: no package name specified");
12530                    pw.println("Use -h for help.");
12531                } else {
12532                    dumpPackage = args[opti];
12533                    opti++;
12534                    newArgs = new String[args.length - opti];
12535                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12536                            args.length - opti);
12537                    args = newArgs;
12538                    opti = 0;
12539                    more = true;
12540                }
12541            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12542                synchronized (this) {
12543                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12544                }
12545            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12546                synchronized (this) {
12547                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12548                }
12549            } else if ("write".equals(cmd)) {
12550                mTaskPersister.flush();
12551                pw.println("All tasks persisted.");
12552                return;
12553            } else if ("track-associations".equals(cmd)) {
12554                synchronized (this) {
12555                    if (!mTrackingAssociations) {
12556                        mTrackingAssociations = true;
12557                        pw.println("Association tracking started.");
12558                    } else {
12559                        pw.println("Association tracking already enabled.");
12560                    }
12561                }
12562                return;
12563            } else if ("untrack-associations".equals(cmd)) {
12564                synchronized (this) {
12565                    if (mTrackingAssociations) {
12566                        mTrackingAssociations = false;
12567                        mAssociations.clear();
12568                        pw.println("Association tracking stopped.");
12569                    } else {
12570                        pw.println("Association tracking not running.");
12571                    }
12572                }
12573                return;
12574            } else {
12575                // Dumping a single activity?
12576                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12577                    pw.println("Bad activity command, or no activities match: " + cmd);
12578                    pw.println("Use -h for help.");
12579                }
12580            }
12581            if (!more) {
12582                Binder.restoreCallingIdentity(origId);
12583                return;
12584            }
12585        }
12586
12587        // No piece of data specified, dump everything.
12588        synchronized (this) {
12589            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12590            pw.println();
12591            if (dumpAll) {
12592                pw.println("-------------------------------------------------------------------------------");
12593            }
12594            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12595            pw.println();
12596            if (dumpAll) {
12597                pw.println("-------------------------------------------------------------------------------");
12598            }
12599            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12600            pw.println();
12601            if (dumpAll) {
12602                pw.println("-------------------------------------------------------------------------------");
12603            }
12604            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12605            pw.println();
12606            if (dumpAll) {
12607                pw.println("-------------------------------------------------------------------------------");
12608            }
12609            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12610            pw.println();
12611            if (dumpAll) {
12612                pw.println("-------------------------------------------------------------------------------");
12613            }
12614            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12615            if (mAssociations.size() > 0) {
12616                pw.println();
12617                if (dumpAll) {
12618                    pw.println("-------------------------------------------------------------------------------");
12619                }
12620                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12621            }
12622            pw.println();
12623            if (dumpAll) {
12624                pw.println("-------------------------------------------------------------------------------");
12625            }
12626            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12627        }
12628        Binder.restoreCallingIdentity(origId);
12629    }
12630
12631    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12632            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12633        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12634
12635        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12636                dumpPackage);
12637        boolean needSep = printedAnything;
12638
12639        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12640                dumpPackage, needSep, "  mFocusedActivity: ");
12641        if (printed) {
12642            printedAnything = true;
12643            needSep = false;
12644        }
12645
12646        if (dumpPackage == null) {
12647            if (needSep) {
12648                pw.println();
12649            }
12650            needSep = true;
12651            printedAnything = true;
12652            mStackSupervisor.dump(pw, "  ");
12653        }
12654
12655        if (!printedAnything) {
12656            pw.println("  (nothing)");
12657        }
12658    }
12659
12660    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12661            int opti, boolean dumpAll, String dumpPackage) {
12662        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12663
12664        boolean printedAnything = false;
12665
12666        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12667            boolean printedHeader = false;
12668
12669            final int N = mRecentTasks.size();
12670            for (int i=0; i<N; i++) {
12671                TaskRecord tr = mRecentTasks.get(i);
12672                if (dumpPackage != null) {
12673                    if (tr.realActivity == null ||
12674                            !dumpPackage.equals(tr.realActivity)) {
12675                        continue;
12676                    }
12677                }
12678                if (!printedHeader) {
12679                    pw.println("  Recent tasks:");
12680                    printedHeader = true;
12681                    printedAnything = true;
12682                }
12683                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12684                        pw.println(tr);
12685                if (dumpAll) {
12686                    mRecentTasks.get(i).dump(pw, "    ");
12687                }
12688            }
12689        }
12690
12691        if (!printedAnything) {
12692            pw.println("  (nothing)");
12693        }
12694    }
12695
12696    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12697            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12698        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12699
12700        int dumpUid = 0;
12701        if (dumpPackage != null) {
12702            IPackageManager pm = AppGlobals.getPackageManager();
12703            try {
12704                dumpUid = pm.getPackageUid(dumpPackage, 0);
12705            } catch (RemoteException e) {
12706            }
12707        }
12708
12709        boolean printedAnything = false;
12710
12711        final long now = SystemClock.uptimeMillis();
12712
12713        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12714            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12715                    = mAssociations.valueAt(i1);
12716            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12717                SparseArray<ArrayMap<String, Association>> sourceUids
12718                        = targetComponents.valueAt(i2);
12719                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12720                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12721                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12722                        Association ass = sourceProcesses.valueAt(i4);
12723                        if (dumpPackage != null) {
12724                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12725                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12726                                continue;
12727                            }
12728                        }
12729                        printedAnything = true;
12730                        pw.print("  ");
12731                        pw.print(ass.mTargetProcess);
12732                        pw.print("/");
12733                        UserHandle.formatUid(pw, ass.mTargetUid);
12734                        pw.print(" <- ");
12735                        pw.print(ass.mSourceProcess);
12736                        pw.print("/");
12737                        UserHandle.formatUid(pw, ass.mSourceUid);
12738                        pw.println();
12739                        pw.print("    via ");
12740                        pw.print(ass.mTargetComponent.flattenToShortString());
12741                        pw.println();
12742                        pw.print("    ");
12743                        long dur = ass.mTime;
12744                        if (ass.mNesting > 0) {
12745                            dur += now - ass.mStartTime;
12746                        }
12747                        TimeUtils.formatDuration(dur, pw);
12748                        pw.print(" (");
12749                        pw.print(ass.mCount);
12750                        pw.println(" times)");
12751                        if (ass.mNesting > 0) {
12752                            pw.print("    ");
12753                            pw.print(" Currently active: ");
12754                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12755                            pw.println();
12756                        }
12757                    }
12758                }
12759            }
12760
12761        }
12762
12763        if (!printedAnything) {
12764            pw.println("  (nothing)");
12765        }
12766    }
12767
12768    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12769            int opti, boolean dumpAll, String dumpPackage) {
12770        boolean needSep = false;
12771        boolean printedAnything = false;
12772        int numPers = 0;
12773
12774        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12775
12776        if (dumpAll) {
12777            final int NP = mProcessNames.getMap().size();
12778            for (int ip=0; ip<NP; ip++) {
12779                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12780                final int NA = procs.size();
12781                for (int ia=0; ia<NA; ia++) {
12782                    ProcessRecord r = procs.valueAt(ia);
12783                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12784                        continue;
12785                    }
12786                    if (!needSep) {
12787                        pw.println("  All known processes:");
12788                        needSep = true;
12789                        printedAnything = true;
12790                    }
12791                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12792                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12793                        pw.print(" "); pw.println(r);
12794                    r.dump(pw, "    ");
12795                    if (r.persistent) {
12796                        numPers++;
12797                    }
12798                }
12799            }
12800        }
12801
12802        if (mIsolatedProcesses.size() > 0) {
12803            boolean printed = false;
12804            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12805                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12806                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12807                    continue;
12808                }
12809                if (!printed) {
12810                    if (needSep) {
12811                        pw.println();
12812                    }
12813                    pw.println("  Isolated process list (sorted by uid):");
12814                    printedAnything = true;
12815                    printed = true;
12816                    needSep = true;
12817                }
12818                pw.println(String.format("%sIsolated #%2d: %s",
12819                        "    ", i, r.toString()));
12820            }
12821        }
12822
12823        if (mLruProcesses.size() > 0) {
12824            if (needSep) {
12825                pw.println();
12826            }
12827            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12828                    pw.print(" total, non-act at ");
12829                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12830                    pw.print(", non-svc at ");
12831                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12832                    pw.println("):");
12833            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12834            needSep = true;
12835            printedAnything = true;
12836        }
12837
12838        if (dumpAll || dumpPackage != null) {
12839            synchronized (mPidsSelfLocked) {
12840                boolean printed = false;
12841                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12842                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12843                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12844                        continue;
12845                    }
12846                    if (!printed) {
12847                        if (needSep) pw.println();
12848                        needSep = true;
12849                        pw.println("  PID mappings:");
12850                        printed = true;
12851                        printedAnything = true;
12852                    }
12853                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12854                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12855                }
12856            }
12857        }
12858
12859        if (mForegroundProcesses.size() > 0) {
12860            synchronized (mPidsSelfLocked) {
12861                boolean printed = false;
12862                for (int i=0; i<mForegroundProcesses.size(); i++) {
12863                    ProcessRecord r = mPidsSelfLocked.get(
12864                            mForegroundProcesses.valueAt(i).pid);
12865                    if (dumpPackage != null && (r == null
12866                            || !r.pkgList.containsKey(dumpPackage))) {
12867                        continue;
12868                    }
12869                    if (!printed) {
12870                        if (needSep) pw.println();
12871                        needSep = true;
12872                        pw.println("  Foreground Processes:");
12873                        printed = true;
12874                        printedAnything = true;
12875                    }
12876                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12877                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12878                }
12879            }
12880        }
12881
12882        if (mPersistentStartingProcesses.size() > 0) {
12883            if (needSep) pw.println();
12884            needSep = true;
12885            printedAnything = true;
12886            pw.println("  Persisent processes that are starting:");
12887            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12888                    "Starting Norm", "Restarting PERS", dumpPackage);
12889        }
12890
12891        if (mRemovedProcesses.size() > 0) {
12892            if (needSep) pw.println();
12893            needSep = true;
12894            printedAnything = true;
12895            pw.println("  Processes that are being removed:");
12896            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12897                    "Removed Norm", "Removed PERS", dumpPackage);
12898        }
12899
12900        if (mProcessesOnHold.size() > 0) {
12901            if (needSep) pw.println();
12902            needSep = true;
12903            printedAnything = true;
12904            pw.println("  Processes that are on old until the system is ready:");
12905            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12906                    "OnHold Norm", "OnHold PERS", dumpPackage);
12907        }
12908
12909        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12910
12911        if (mProcessCrashTimes.getMap().size() > 0) {
12912            boolean printed = false;
12913            long now = SystemClock.uptimeMillis();
12914            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12915            final int NP = pmap.size();
12916            for (int ip=0; ip<NP; ip++) {
12917                String pname = pmap.keyAt(ip);
12918                SparseArray<Long> uids = pmap.valueAt(ip);
12919                final int N = uids.size();
12920                for (int i=0; i<N; i++) {
12921                    int puid = uids.keyAt(i);
12922                    ProcessRecord r = mProcessNames.get(pname, puid);
12923                    if (dumpPackage != null && (r == null
12924                            || !r.pkgList.containsKey(dumpPackage))) {
12925                        continue;
12926                    }
12927                    if (!printed) {
12928                        if (needSep) pw.println();
12929                        needSep = true;
12930                        pw.println("  Time since processes crashed:");
12931                        printed = true;
12932                        printedAnything = true;
12933                    }
12934                    pw.print("    Process "); pw.print(pname);
12935                            pw.print(" uid "); pw.print(puid);
12936                            pw.print(": last crashed ");
12937                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12938                            pw.println(" ago");
12939                }
12940            }
12941        }
12942
12943        if (mBadProcesses.getMap().size() > 0) {
12944            boolean printed = false;
12945            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12946            final int NP = pmap.size();
12947            for (int ip=0; ip<NP; ip++) {
12948                String pname = pmap.keyAt(ip);
12949                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12950                final int N = uids.size();
12951                for (int i=0; i<N; i++) {
12952                    int puid = uids.keyAt(i);
12953                    ProcessRecord r = mProcessNames.get(pname, puid);
12954                    if (dumpPackage != null && (r == null
12955                            || !r.pkgList.containsKey(dumpPackage))) {
12956                        continue;
12957                    }
12958                    if (!printed) {
12959                        if (needSep) pw.println();
12960                        needSep = true;
12961                        pw.println("  Bad processes:");
12962                        printedAnything = true;
12963                    }
12964                    BadProcessInfo info = uids.valueAt(i);
12965                    pw.print("    Bad process "); pw.print(pname);
12966                            pw.print(" uid "); pw.print(puid);
12967                            pw.print(": crashed at time "); pw.println(info.time);
12968                    if (info.shortMsg != null) {
12969                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12970                    }
12971                    if (info.longMsg != null) {
12972                        pw.print("      Long msg: "); pw.println(info.longMsg);
12973                    }
12974                    if (info.stack != null) {
12975                        pw.println("      Stack:");
12976                        int lastPos = 0;
12977                        for (int pos=0; pos<info.stack.length(); pos++) {
12978                            if (info.stack.charAt(pos) == '\n') {
12979                                pw.print("        ");
12980                                pw.write(info.stack, lastPos, pos-lastPos);
12981                                pw.println();
12982                                lastPos = pos+1;
12983                            }
12984                        }
12985                        if (lastPos < info.stack.length()) {
12986                            pw.print("        ");
12987                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12988                            pw.println();
12989                        }
12990                    }
12991                }
12992            }
12993        }
12994
12995        if (dumpPackage == null) {
12996            pw.println();
12997            needSep = false;
12998            pw.println("  mStartedUsers:");
12999            for (int i=0; i<mStartedUsers.size(); i++) {
13000                UserStartedState uss = mStartedUsers.valueAt(i);
13001                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13002                        pw.print(": "); uss.dump("", pw);
13003            }
13004            pw.print("  mStartedUserArray: [");
13005            for (int i=0; i<mStartedUserArray.length; i++) {
13006                if (i > 0) pw.print(", ");
13007                pw.print(mStartedUserArray[i]);
13008            }
13009            pw.println("]");
13010            pw.print("  mUserLru: [");
13011            for (int i=0; i<mUserLru.size(); i++) {
13012                if (i > 0) pw.print(", ");
13013                pw.print(mUserLru.get(i));
13014            }
13015            pw.println("]");
13016            if (dumpAll) {
13017                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13018            }
13019            synchronized (mUserProfileGroupIdsSelfLocked) {
13020                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13021                    pw.println("  mUserProfileGroupIds:");
13022                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13023                        pw.print("    User #");
13024                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13025                        pw.print(" -> profile #");
13026                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13027                    }
13028                }
13029            }
13030        }
13031        if (mHomeProcess != null && (dumpPackage == null
13032                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13033            if (needSep) {
13034                pw.println();
13035                needSep = false;
13036            }
13037            pw.println("  mHomeProcess: " + mHomeProcess);
13038        }
13039        if (mPreviousProcess != null && (dumpPackage == null
13040                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13041            if (needSep) {
13042                pw.println();
13043                needSep = false;
13044            }
13045            pw.println("  mPreviousProcess: " + mPreviousProcess);
13046        }
13047        if (dumpAll) {
13048            StringBuilder sb = new StringBuilder(128);
13049            sb.append("  mPreviousProcessVisibleTime: ");
13050            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13051            pw.println(sb);
13052        }
13053        if (mHeavyWeightProcess != null && (dumpPackage == null
13054                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13055            if (needSep) {
13056                pw.println();
13057                needSep = false;
13058            }
13059            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13060        }
13061        if (dumpPackage == null) {
13062            pw.println("  mConfiguration: " + mConfiguration);
13063        }
13064        if (dumpAll) {
13065            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13066            if (mCompatModePackages.getPackages().size() > 0) {
13067                boolean printed = false;
13068                for (Map.Entry<String, Integer> entry
13069                        : mCompatModePackages.getPackages().entrySet()) {
13070                    String pkg = entry.getKey();
13071                    int mode = entry.getValue();
13072                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13073                        continue;
13074                    }
13075                    if (!printed) {
13076                        pw.println("  mScreenCompatPackages:");
13077                        printed = true;
13078                    }
13079                    pw.print("    "); pw.print(pkg); pw.print(": ");
13080                            pw.print(mode); pw.println();
13081                }
13082            }
13083        }
13084        if (dumpPackage == null) {
13085            pw.println("  mWakefulness="
13086                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13087            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13088                    + lockScreenShownToString());
13089            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13090                    + " mTestPssMode=" + mTestPssMode);
13091        }
13092        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13093                || mOrigWaitForDebugger) {
13094            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13095                    || dumpPackage.equals(mOrigDebugApp)) {
13096                if (needSep) {
13097                    pw.println();
13098                    needSep = false;
13099                }
13100                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13101                        + " mDebugTransient=" + mDebugTransient
13102                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13103            }
13104        }
13105        if (mOpenGlTraceApp != null) {
13106            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13107                if (needSep) {
13108                    pw.println();
13109                    needSep = false;
13110                }
13111                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13112            }
13113        }
13114        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13115                || mProfileFd != null) {
13116            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13117                if (needSep) {
13118                    pw.println();
13119                    needSep = false;
13120                }
13121                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13122                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13123                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13124                        + mAutoStopProfiler);
13125                pw.println("  mProfileType=" + mProfileType);
13126            }
13127        }
13128        if (dumpPackage == null) {
13129            if (mAlwaysFinishActivities || mController != null) {
13130                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13131                        + " mController=" + mController);
13132            }
13133            if (dumpAll) {
13134                pw.println("  Total persistent processes: " + numPers);
13135                pw.println("  mProcessesReady=" + mProcessesReady
13136                        + " mSystemReady=" + mSystemReady
13137                        + " mBooted=" + mBooted
13138                        + " mFactoryTest=" + mFactoryTest);
13139                pw.println("  mBooting=" + mBooting
13140                        + " mCallFinishBooting=" + mCallFinishBooting
13141                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13142                pw.print("  mLastPowerCheckRealtime=");
13143                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13144                        pw.println("");
13145                pw.print("  mLastPowerCheckUptime=");
13146                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13147                        pw.println("");
13148                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13149                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13150                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13151                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13152                        + " (" + mLruProcesses.size() + " total)"
13153                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13154                        + " mNumServiceProcs=" + mNumServiceProcs
13155                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13156                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13157                        + " mLastMemoryLevel" + mLastMemoryLevel
13158                        + " mLastNumProcesses" + mLastNumProcesses);
13159                long now = SystemClock.uptimeMillis();
13160                pw.print("  mLastIdleTime=");
13161                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13162                        pw.print(" mLowRamSinceLastIdle=");
13163                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13164                        pw.println();
13165            }
13166        }
13167
13168        if (!printedAnything) {
13169            pw.println("  (nothing)");
13170        }
13171    }
13172
13173    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13174            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13175        if (mProcessesToGc.size() > 0) {
13176            boolean printed = false;
13177            long now = SystemClock.uptimeMillis();
13178            for (int i=0; i<mProcessesToGc.size(); i++) {
13179                ProcessRecord proc = mProcessesToGc.get(i);
13180                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13181                    continue;
13182                }
13183                if (!printed) {
13184                    if (needSep) pw.println();
13185                    needSep = true;
13186                    pw.println("  Processes that are waiting to GC:");
13187                    printed = true;
13188                }
13189                pw.print("    Process "); pw.println(proc);
13190                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13191                        pw.print(", last gced=");
13192                        pw.print(now-proc.lastRequestedGc);
13193                        pw.print(" ms ago, last lowMem=");
13194                        pw.print(now-proc.lastLowMemory);
13195                        pw.println(" ms ago");
13196
13197            }
13198        }
13199        return needSep;
13200    }
13201
13202    void printOomLevel(PrintWriter pw, String name, int adj) {
13203        pw.print("    ");
13204        if (adj >= 0) {
13205            pw.print(' ');
13206            if (adj < 10) pw.print(' ');
13207        } else {
13208            if (adj > -10) pw.print(' ');
13209        }
13210        pw.print(adj);
13211        pw.print(": ");
13212        pw.print(name);
13213        pw.print(" (");
13214        pw.print(mProcessList.getMemLevel(adj)/1024);
13215        pw.println(" kB)");
13216    }
13217
13218    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13219            int opti, boolean dumpAll) {
13220        boolean needSep = false;
13221
13222        if (mLruProcesses.size() > 0) {
13223            if (needSep) pw.println();
13224            needSep = true;
13225            pw.println("  OOM levels:");
13226            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13227            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13228            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13229            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13230            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13231            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13232            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13233            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13234            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13235            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13236            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13237            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13238            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13239            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13240
13241            if (needSep) pw.println();
13242            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13243                    pw.print(" total, non-act at ");
13244                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13245                    pw.print(", non-svc at ");
13246                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13247                    pw.println("):");
13248            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13249            needSep = true;
13250        }
13251
13252        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13253
13254        pw.println();
13255        pw.println("  mHomeProcess: " + mHomeProcess);
13256        pw.println("  mPreviousProcess: " + mPreviousProcess);
13257        if (mHeavyWeightProcess != null) {
13258            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13259        }
13260
13261        return true;
13262    }
13263
13264    /**
13265     * There are three ways to call this:
13266     *  - no provider specified: dump all the providers
13267     *  - a flattened component name that matched an existing provider was specified as the
13268     *    first arg: dump that one provider
13269     *  - the first arg isn't the flattened component name of an existing provider:
13270     *    dump all providers whose component contains the first arg as a substring
13271     */
13272    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13273            int opti, boolean dumpAll) {
13274        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13275    }
13276
13277    static class ItemMatcher {
13278        ArrayList<ComponentName> components;
13279        ArrayList<String> strings;
13280        ArrayList<Integer> objects;
13281        boolean all;
13282
13283        ItemMatcher() {
13284            all = true;
13285        }
13286
13287        void build(String name) {
13288            ComponentName componentName = ComponentName.unflattenFromString(name);
13289            if (componentName != null) {
13290                if (components == null) {
13291                    components = new ArrayList<ComponentName>();
13292                }
13293                components.add(componentName);
13294                all = false;
13295            } else {
13296                int objectId = 0;
13297                // Not a '/' separated full component name; maybe an object ID?
13298                try {
13299                    objectId = Integer.parseInt(name, 16);
13300                    if (objects == null) {
13301                        objects = new ArrayList<Integer>();
13302                    }
13303                    objects.add(objectId);
13304                    all = false;
13305                } catch (RuntimeException e) {
13306                    // Not an integer; just do string match.
13307                    if (strings == null) {
13308                        strings = new ArrayList<String>();
13309                    }
13310                    strings.add(name);
13311                    all = false;
13312                }
13313            }
13314        }
13315
13316        int build(String[] args, int opti) {
13317            for (; opti<args.length; opti++) {
13318                String name = args[opti];
13319                if ("--".equals(name)) {
13320                    return opti+1;
13321                }
13322                build(name);
13323            }
13324            return opti;
13325        }
13326
13327        boolean match(Object object, ComponentName comp) {
13328            if (all) {
13329                return true;
13330            }
13331            if (components != null) {
13332                for (int i=0; i<components.size(); i++) {
13333                    if (components.get(i).equals(comp)) {
13334                        return true;
13335                    }
13336                }
13337            }
13338            if (objects != null) {
13339                for (int i=0; i<objects.size(); i++) {
13340                    if (System.identityHashCode(object) == objects.get(i)) {
13341                        return true;
13342                    }
13343                }
13344            }
13345            if (strings != null) {
13346                String flat = comp.flattenToString();
13347                for (int i=0; i<strings.size(); i++) {
13348                    if (flat.contains(strings.get(i))) {
13349                        return true;
13350                    }
13351                }
13352            }
13353            return false;
13354        }
13355    }
13356
13357    /**
13358     * There are three things that cmd can be:
13359     *  - a flattened component name that matches an existing activity
13360     *  - the cmd arg isn't the flattened component name of an existing activity:
13361     *    dump all activity whose component contains the cmd as a substring
13362     *  - A hex number of the ActivityRecord object instance.
13363     */
13364    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13365            int opti, boolean dumpAll) {
13366        ArrayList<ActivityRecord> activities;
13367
13368        synchronized (this) {
13369            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13370        }
13371
13372        if (activities.size() <= 0) {
13373            return false;
13374        }
13375
13376        String[] newArgs = new String[args.length - opti];
13377        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13378
13379        TaskRecord lastTask = null;
13380        boolean needSep = false;
13381        for (int i=activities.size()-1; i>=0; i--) {
13382            ActivityRecord r = activities.get(i);
13383            if (needSep) {
13384                pw.println();
13385            }
13386            needSep = true;
13387            synchronized (this) {
13388                if (lastTask != r.task) {
13389                    lastTask = r.task;
13390                    pw.print("TASK "); pw.print(lastTask.affinity);
13391                            pw.print(" id="); pw.println(lastTask.taskId);
13392                    if (dumpAll) {
13393                        lastTask.dump(pw, "  ");
13394                    }
13395                }
13396            }
13397            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13398        }
13399        return true;
13400    }
13401
13402    /**
13403     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13404     * there is a thread associated with the activity.
13405     */
13406    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13407            final ActivityRecord r, String[] args, boolean dumpAll) {
13408        String innerPrefix = prefix + "  ";
13409        synchronized (this) {
13410            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13411                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13412                    pw.print(" pid=");
13413                    if (r.app != null) pw.println(r.app.pid);
13414                    else pw.println("(not running)");
13415            if (dumpAll) {
13416                r.dump(pw, innerPrefix);
13417            }
13418        }
13419        if (r.app != null && r.app.thread != null) {
13420            // flush anything that is already in the PrintWriter since the thread is going
13421            // to write to the file descriptor directly
13422            pw.flush();
13423            try {
13424                TransferPipe tp = new TransferPipe();
13425                try {
13426                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13427                            r.appToken, innerPrefix, args);
13428                    tp.go(fd);
13429                } finally {
13430                    tp.kill();
13431                }
13432            } catch (IOException e) {
13433                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13434            } catch (RemoteException e) {
13435                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13436            }
13437        }
13438    }
13439
13440    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13441            int opti, boolean dumpAll, String dumpPackage) {
13442        boolean needSep = false;
13443        boolean onlyHistory = false;
13444        boolean printedAnything = false;
13445
13446        if ("history".equals(dumpPackage)) {
13447            if (opti < args.length && "-s".equals(args[opti])) {
13448                dumpAll = false;
13449            }
13450            onlyHistory = true;
13451            dumpPackage = null;
13452        }
13453
13454        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13455        if (!onlyHistory && dumpAll) {
13456            if (mRegisteredReceivers.size() > 0) {
13457                boolean printed = false;
13458                Iterator it = mRegisteredReceivers.values().iterator();
13459                while (it.hasNext()) {
13460                    ReceiverList r = (ReceiverList)it.next();
13461                    if (dumpPackage != null && (r.app == null ||
13462                            !dumpPackage.equals(r.app.info.packageName))) {
13463                        continue;
13464                    }
13465                    if (!printed) {
13466                        pw.println("  Registered Receivers:");
13467                        needSep = true;
13468                        printed = true;
13469                        printedAnything = true;
13470                    }
13471                    pw.print("  * "); pw.println(r);
13472                    r.dump(pw, "    ");
13473                }
13474            }
13475
13476            if (mReceiverResolver.dump(pw, needSep ?
13477                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13478                    "    ", dumpPackage, false, false)) {
13479                needSep = true;
13480                printedAnything = true;
13481            }
13482        }
13483
13484        for (BroadcastQueue q : mBroadcastQueues) {
13485            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13486            printedAnything |= needSep;
13487        }
13488
13489        needSep = true;
13490
13491        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13492            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13493                if (needSep) {
13494                    pw.println();
13495                }
13496                needSep = true;
13497                printedAnything = true;
13498                pw.print("  Sticky broadcasts for user ");
13499                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13500                StringBuilder sb = new StringBuilder(128);
13501                for (Map.Entry<String, ArrayList<Intent>> ent
13502                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13503                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13504                    if (dumpAll) {
13505                        pw.println(":");
13506                        ArrayList<Intent> intents = ent.getValue();
13507                        final int N = intents.size();
13508                        for (int i=0; i<N; i++) {
13509                            sb.setLength(0);
13510                            sb.append("    Intent: ");
13511                            intents.get(i).toShortString(sb, false, true, false, false);
13512                            pw.println(sb.toString());
13513                            Bundle bundle = intents.get(i).getExtras();
13514                            if (bundle != null) {
13515                                pw.print("      ");
13516                                pw.println(bundle.toString());
13517                            }
13518                        }
13519                    } else {
13520                        pw.println("");
13521                    }
13522                }
13523            }
13524        }
13525
13526        if (!onlyHistory && dumpAll) {
13527            pw.println();
13528            for (BroadcastQueue queue : mBroadcastQueues) {
13529                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13530                        + queue.mBroadcastsScheduled);
13531            }
13532            pw.println("  mHandler:");
13533            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13534            needSep = true;
13535            printedAnything = true;
13536        }
13537
13538        if (!printedAnything) {
13539            pw.println("  (nothing)");
13540        }
13541    }
13542
13543    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13544            int opti, boolean dumpAll, String dumpPackage) {
13545        boolean needSep;
13546        boolean printedAnything = false;
13547
13548        ItemMatcher matcher = new ItemMatcher();
13549        matcher.build(args, opti);
13550
13551        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13552
13553        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13554        printedAnything |= needSep;
13555
13556        if (mLaunchingProviders.size() > 0) {
13557            boolean printed = false;
13558            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13559                ContentProviderRecord r = mLaunchingProviders.get(i);
13560                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13561                    continue;
13562                }
13563                if (!printed) {
13564                    if (needSep) pw.println();
13565                    needSep = true;
13566                    pw.println("  Launching content providers:");
13567                    printed = true;
13568                    printedAnything = true;
13569                }
13570                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13571                        pw.println(r);
13572            }
13573        }
13574
13575        if (mGrantedUriPermissions.size() > 0) {
13576            boolean printed = false;
13577            int dumpUid = -2;
13578            if (dumpPackage != null) {
13579                try {
13580                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13581                } catch (NameNotFoundException e) {
13582                    dumpUid = -1;
13583                }
13584            }
13585            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13586                int uid = mGrantedUriPermissions.keyAt(i);
13587                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13588                    continue;
13589                }
13590                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13591                if (!printed) {
13592                    if (needSep) pw.println();
13593                    needSep = true;
13594                    pw.println("  Granted Uri Permissions:");
13595                    printed = true;
13596                    printedAnything = true;
13597                }
13598                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13599                for (UriPermission perm : perms.values()) {
13600                    pw.print("    "); pw.println(perm);
13601                    if (dumpAll) {
13602                        perm.dump(pw, "      ");
13603                    }
13604                }
13605            }
13606        }
13607
13608        if (!printedAnything) {
13609            pw.println("  (nothing)");
13610        }
13611    }
13612
13613    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13614            int opti, boolean dumpAll, String dumpPackage) {
13615        boolean printed = false;
13616
13617        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13618
13619        if (mIntentSenderRecords.size() > 0) {
13620            Iterator<WeakReference<PendingIntentRecord>> it
13621                    = mIntentSenderRecords.values().iterator();
13622            while (it.hasNext()) {
13623                WeakReference<PendingIntentRecord> ref = it.next();
13624                PendingIntentRecord rec = ref != null ? ref.get(): null;
13625                if (dumpPackage != null && (rec == null
13626                        || !dumpPackage.equals(rec.key.packageName))) {
13627                    continue;
13628                }
13629                printed = true;
13630                if (rec != null) {
13631                    pw.print("  * "); pw.println(rec);
13632                    if (dumpAll) {
13633                        rec.dump(pw, "    ");
13634                    }
13635                } else {
13636                    pw.print("  * "); pw.println(ref);
13637                }
13638            }
13639        }
13640
13641        if (!printed) {
13642            pw.println("  (nothing)");
13643        }
13644    }
13645
13646    private static final int dumpProcessList(PrintWriter pw,
13647            ActivityManagerService service, List list,
13648            String prefix, String normalLabel, String persistentLabel,
13649            String dumpPackage) {
13650        int numPers = 0;
13651        final int N = list.size()-1;
13652        for (int i=N; i>=0; i--) {
13653            ProcessRecord r = (ProcessRecord)list.get(i);
13654            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13655                continue;
13656            }
13657            pw.println(String.format("%s%s #%2d: %s",
13658                    prefix, (r.persistent ? persistentLabel : normalLabel),
13659                    i, r.toString()));
13660            if (r.persistent) {
13661                numPers++;
13662            }
13663        }
13664        return numPers;
13665    }
13666
13667    private static final boolean dumpProcessOomList(PrintWriter pw,
13668            ActivityManagerService service, List<ProcessRecord> origList,
13669            String prefix, String normalLabel, String persistentLabel,
13670            boolean inclDetails, String dumpPackage) {
13671
13672        ArrayList<Pair<ProcessRecord, Integer>> list
13673                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13674        for (int i=0; i<origList.size(); i++) {
13675            ProcessRecord r = origList.get(i);
13676            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13677                continue;
13678            }
13679            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13680        }
13681
13682        if (list.size() <= 0) {
13683            return false;
13684        }
13685
13686        Comparator<Pair<ProcessRecord, Integer>> comparator
13687                = new Comparator<Pair<ProcessRecord, Integer>>() {
13688            @Override
13689            public int compare(Pair<ProcessRecord, Integer> object1,
13690                    Pair<ProcessRecord, Integer> object2) {
13691                if (object1.first.setAdj != object2.first.setAdj) {
13692                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13693                }
13694                if (object1.second.intValue() != object2.second.intValue()) {
13695                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13696                }
13697                return 0;
13698            }
13699        };
13700
13701        Collections.sort(list, comparator);
13702
13703        final long curRealtime = SystemClock.elapsedRealtime();
13704        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13705        final long curUptime = SystemClock.uptimeMillis();
13706        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13707
13708        for (int i=list.size()-1; i>=0; i--) {
13709            ProcessRecord r = list.get(i).first;
13710            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13711            char schedGroup;
13712            switch (r.setSchedGroup) {
13713                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13714                    schedGroup = 'B';
13715                    break;
13716                case Process.THREAD_GROUP_DEFAULT:
13717                    schedGroup = 'F';
13718                    break;
13719                default:
13720                    schedGroup = '?';
13721                    break;
13722            }
13723            char foreground;
13724            if (r.foregroundActivities) {
13725                foreground = 'A';
13726            } else if (r.foregroundServices) {
13727                foreground = 'S';
13728            } else {
13729                foreground = ' ';
13730            }
13731            String procState = ProcessList.makeProcStateString(r.curProcState);
13732            pw.print(prefix);
13733            pw.print(r.persistent ? persistentLabel : normalLabel);
13734            pw.print(" #");
13735            int num = (origList.size()-1)-list.get(i).second;
13736            if (num < 10) pw.print(' ');
13737            pw.print(num);
13738            pw.print(": ");
13739            pw.print(oomAdj);
13740            pw.print(' ');
13741            pw.print(schedGroup);
13742            pw.print('/');
13743            pw.print(foreground);
13744            pw.print('/');
13745            pw.print(procState);
13746            pw.print(" trm:");
13747            if (r.trimMemoryLevel < 10) pw.print(' ');
13748            pw.print(r.trimMemoryLevel);
13749            pw.print(' ');
13750            pw.print(r.toShortString());
13751            pw.print(" (");
13752            pw.print(r.adjType);
13753            pw.println(')');
13754            if (r.adjSource != null || r.adjTarget != null) {
13755                pw.print(prefix);
13756                pw.print("    ");
13757                if (r.adjTarget instanceof ComponentName) {
13758                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13759                } else if (r.adjTarget != null) {
13760                    pw.print(r.adjTarget.toString());
13761                } else {
13762                    pw.print("{null}");
13763                }
13764                pw.print("<=");
13765                if (r.adjSource instanceof ProcessRecord) {
13766                    pw.print("Proc{");
13767                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13768                    pw.println("}");
13769                } else if (r.adjSource != null) {
13770                    pw.println(r.adjSource.toString());
13771                } else {
13772                    pw.println("{null}");
13773                }
13774            }
13775            if (inclDetails) {
13776                pw.print(prefix);
13777                pw.print("    ");
13778                pw.print("oom: max="); pw.print(r.maxAdj);
13779                pw.print(" curRaw="); pw.print(r.curRawAdj);
13780                pw.print(" setRaw="); pw.print(r.setRawAdj);
13781                pw.print(" cur="); pw.print(r.curAdj);
13782                pw.print(" set="); pw.println(r.setAdj);
13783                pw.print(prefix);
13784                pw.print("    ");
13785                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13786                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13787                pw.print(" lastPss="); pw.print(r.lastPss);
13788                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13789                pw.print(prefix);
13790                pw.print("    ");
13791                pw.print("cached="); pw.print(r.cached);
13792                pw.print(" empty="); pw.print(r.empty);
13793                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13794
13795                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13796                    if (r.lastWakeTime != 0) {
13797                        long wtime;
13798                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13799                        synchronized (stats) {
13800                            wtime = stats.getProcessWakeTime(r.info.uid,
13801                                    r.pid, curRealtime);
13802                        }
13803                        long timeUsed = wtime - r.lastWakeTime;
13804                        pw.print(prefix);
13805                        pw.print("    ");
13806                        pw.print("keep awake over ");
13807                        TimeUtils.formatDuration(realtimeSince, pw);
13808                        pw.print(" used ");
13809                        TimeUtils.formatDuration(timeUsed, pw);
13810                        pw.print(" (");
13811                        pw.print((timeUsed*100)/realtimeSince);
13812                        pw.println("%)");
13813                    }
13814                    if (r.lastCpuTime != 0) {
13815                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13816                        pw.print(prefix);
13817                        pw.print("    ");
13818                        pw.print("run cpu over ");
13819                        TimeUtils.formatDuration(uptimeSince, pw);
13820                        pw.print(" used ");
13821                        TimeUtils.formatDuration(timeUsed, pw);
13822                        pw.print(" (");
13823                        pw.print((timeUsed*100)/uptimeSince);
13824                        pw.println("%)");
13825                    }
13826                }
13827            }
13828        }
13829        return true;
13830    }
13831
13832    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13833            String[] args) {
13834        ArrayList<ProcessRecord> procs;
13835        synchronized (this) {
13836            if (args != null && args.length > start
13837                    && args[start].charAt(0) != '-') {
13838                procs = new ArrayList<ProcessRecord>();
13839                int pid = -1;
13840                try {
13841                    pid = Integer.parseInt(args[start]);
13842                } catch (NumberFormatException e) {
13843                }
13844                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13845                    ProcessRecord proc = mLruProcesses.get(i);
13846                    if (proc.pid == pid) {
13847                        procs.add(proc);
13848                    } else if (allPkgs && proc.pkgList != null
13849                            && proc.pkgList.containsKey(args[start])) {
13850                        procs.add(proc);
13851                    } else if (proc.processName.equals(args[start])) {
13852                        procs.add(proc);
13853                    }
13854                }
13855                if (procs.size() <= 0) {
13856                    return null;
13857                }
13858            } else {
13859                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13860            }
13861        }
13862        return procs;
13863    }
13864
13865    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13866            PrintWriter pw, String[] args) {
13867        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13868        if (procs == null) {
13869            pw.println("No process found for: " + args[0]);
13870            return;
13871        }
13872
13873        long uptime = SystemClock.uptimeMillis();
13874        long realtime = SystemClock.elapsedRealtime();
13875        pw.println("Applications Graphics Acceleration Info:");
13876        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13877
13878        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13879            ProcessRecord r = procs.get(i);
13880            if (r.thread != null) {
13881                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13882                pw.flush();
13883                try {
13884                    TransferPipe tp = new TransferPipe();
13885                    try {
13886                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13887                        tp.go(fd);
13888                    } finally {
13889                        tp.kill();
13890                    }
13891                } catch (IOException e) {
13892                    pw.println("Failure while dumping the app: " + r);
13893                    pw.flush();
13894                } catch (RemoteException e) {
13895                    pw.println("Got a RemoteException while dumping the app " + r);
13896                    pw.flush();
13897                }
13898            }
13899        }
13900    }
13901
13902    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13903        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13904        if (procs == null) {
13905            pw.println("No process found for: " + args[0]);
13906            return;
13907        }
13908
13909        pw.println("Applications Database Info:");
13910
13911        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13912            ProcessRecord r = procs.get(i);
13913            if (r.thread != null) {
13914                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13915                pw.flush();
13916                try {
13917                    TransferPipe tp = new TransferPipe();
13918                    try {
13919                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13920                        tp.go(fd);
13921                    } finally {
13922                        tp.kill();
13923                    }
13924                } catch (IOException e) {
13925                    pw.println("Failure while dumping the app: " + r);
13926                    pw.flush();
13927                } catch (RemoteException e) {
13928                    pw.println("Got a RemoteException while dumping the app " + r);
13929                    pw.flush();
13930                }
13931            }
13932        }
13933    }
13934
13935    final static class MemItem {
13936        final boolean isProc;
13937        final String label;
13938        final String shortLabel;
13939        final long pss;
13940        final int id;
13941        final boolean hasActivities;
13942        ArrayList<MemItem> subitems;
13943
13944        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13945                boolean _hasActivities) {
13946            isProc = true;
13947            label = _label;
13948            shortLabel = _shortLabel;
13949            pss = _pss;
13950            id = _id;
13951            hasActivities = _hasActivities;
13952        }
13953
13954        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13955            isProc = false;
13956            label = _label;
13957            shortLabel = _shortLabel;
13958            pss = _pss;
13959            id = _id;
13960            hasActivities = false;
13961        }
13962    }
13963
13964    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13965            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13966        if (sort && !isCompact) {
13967            Collections.sort(items, new Comparator<MemItem>() {
13968                @Override
13969                public int compare(MemItem lhs, MemItem rhs) {
13970                    if (lhs.pss < rhs.pss) {
13971                        return 1;
13972                    } else if (lhs.pss > rhs.pss) {
13973                        return -1;
13974                    }
13975                    return 0;
13976                }
13977            });
13978        }
13979
13980        for (int i=0; i<items.size(); i++) {
13981            MemItem mi = items.get(i);
13982            if (!isCompact) {
13983                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13984            } else if (mi.isProc) {
13985                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13986                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13987                pw.println(mi.hasActivities ? ",a" : ",e");
13988            } else {
13989                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13990                pw.println(mi.pss);
13991            }
13992            if (mi.subitems != null) {
13993                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13994                        true, isCompact);
13995            }
13996        }
13997    }
13998
13999    // These are in KB.
14000    static final long[] DUMP_MEM_BUCKETS = new long[] {
14001        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14002        120*1024, 160*1024, 200*1024,
14003        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14004        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14005    };
14006
14007    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14008            boolean stackLike) {
14009        int start = label.lastIndexOf('.');
14010        if (start >= 0) start++;
14011        else start = 0;
14012        int end = label.length();
14013        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14014            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14015                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14016                out.append(bucket);
14017                out.append(stackLike ? "MB." : "MB ");
14018                out.append(label, start, end);
14019                return;
14020            }
14021        }
14022        out.append(memKB/1024);
14023        out.append(stackLike ? "MB." : "MB ");
14024        out.append(label, start, end);
14025    }
14026
14027    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14028            ProcessList.NATIVE_ADJ,
14029            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14030            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14031            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14032            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14033            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14034            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14035    };
14036    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14037            "Native",
14038            "System", "Persistent", "Persistent Service", "Foreground",
14039            "Visible", "Perceptible",
14040            "Heavy Weight", "Backup",
14041            "A Services", "Home",
14042            "Previous", "B Services", "Cached"
14043    };
14044    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14045            "native",
14046            "sys", "pers", "persvc", "fore",
14047            "vis", "percept",
14048            "heavy", "backup",
14049            "servicea", "home",
14050            "prev", "serviceb", "cached"
14051    };
14052
14053    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14054            long realtime, boolean isCheckinRequest, boolean isCompact) {
14055        if (isCheckinRequest || isCompact) {
14056            // short checkin version
14057            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14058        } else {
14059            pw.println("Applications Memory Usage (kB):");
14060            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14061        }
14062    }
14063
14064    private static final int KSM_SHARED = 0;
14065    private static final int KSM_SHARING = 1;
14066    private static final int KSM_UNSHARED = 2;
14067    private static final int KSM_VOLATILE = 3;
14068
14069    private final long[] getKsmInfo() {
14070        long[] longOut = new long[4];
14071        final int[] SINGLE_LONG_FORMAT = new int[] {
14072            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14073        };
14074        long[] longTmp = new long[1];
14075        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14076                SINGLE_LONG_FORMAT, null, longTmp, null);
14077        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14078        longTmp[0] = 0;
14079        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14080                SINGLE_LONG_FORMAT, null, longTmp, null);
14081        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14082        longTmp[0] = 0;
14083        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14084                SINGLE_LONG_FORMAT, null, longTmp, null);
14085        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14086        longTmp[0] = 0;
14087        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14088                SINGLE_LONG_FORMAT, null, longTmp, null);
14089        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14090        return longOut;
14091    }
14092
14093    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14094            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14095        boolean dumpDetails = false;
14096        boolean dumpFullDetails = false;
14097        boolean dumpDalvik = false;
14098        boolean oomOnly = false;
14099        boolean isCompact = false;
14100        boolean localOnly = false;
14101        boolean packages = false;
14102
14103        int opti = 0;
14104        while (opti < args.length) {
14105            String opt = args[opti];
14106            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14107                break;
14108            }
14109            opti++;
14110            if ("-a".equals(opt)) {
14111                dumpDetails = true;
14112                dumpFullDetails = true;
14113                dumpDalvik = true;
14114            } else if ("-d".equals(opt)) {
14115                dumpDalvik = true;
14116            } else if ("-c".equals(opt)) {
14117                isCompact = true;
14118            } else if ("--oom".equals(opt)) {
14119                oomOnly = true;
14120            } else if ("--local".equals(opt)) {
14121                localOnly = true;
14122            } else if ("--package".equals(opt)) {
14123                packages = true;
14124            } else if ("-h".equals(opt)) {
14125                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14126                pw.println("  -a: include all available information for each process.");
14127                pw.println("  -d: include dalvik details when dumping process details.");
14128                pw.println("  -c: dump in a compact machine-parseable representation.");
14129                pw.println("  --oom: only show processes organized by oom adj.");
14130                pw.println("  --local: only collect details locally, don't call process.");
14131                pw.println("  --package: interpret process arg as package, dumping all");
14132                pw.println("             processes that have loaded that package.");
14133                pw.println("If [process] is specified it can be the name or ");
14134                pw.println("pid of a specific process to dump.");
14135                return;
14136            } else {
14137                pw.println("Unknown argument: " + opt + "; use -h for help");
14138            }
14139        }
14140
14141        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14142        long uptime = SystemClock.uptimeMillis();
14143        long realtime = SystemClock.elapsedRealtime();
14144        final long[] tmpLong = new long[1];
14145
14146        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14147        if (procs == null) {
14148            // No Java processes.  Maybe they want to print a native process.
14149            if (args != null && args.length > opti
14150                    && args[opti].charAt(0) != '-') {
14151                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14152                        = new ArrayList<ProcessCpuTracker.Stats>();
14153                updateCpuStatsNow();
14154                int findPid = -1;
14155                try {
14156                    findPid = Integer.parseInt(args[opti]);
14157                } catch (NumberFormatException e) {
14158                }
14159                synchronized (mProcessCpuTracker) {
14160                    final int N = mProcessCpuTracker.countStats();
14161                    for (int i=0; i<N; i++) {
14162                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14163                        if (st.pid == findPid || (st.baseName != null
14164                                && st.baseName.equals(args[opti]))) {
14165                            nativeProcs.add(st);
14166                        }
14167                    }
14168                }
14169                if (nativeProcs.size() > 0) {
14170                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14171                            isCompact);
14172                    Debug.MemoryInfo mi = null;
14173                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14174                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14175                        final int pid = r.pid;
14176                        if (!isCheckinRequest && dumpDetails) {
14177                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14178                        }
14179                        if (mi == null) {
14180                            mi = new Debug.MemoryInfo();
14181                        }
14182                        if (dumpDetails || (!brief && !oomOnly)) {
14183                            Debug.getMemoryInfo(pid, mi);
14184                        } else {
14185                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14186                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14187                        }
14188                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14189                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14190                        if (isCheckinRequest) {
14191                            pw.println();
14192                        }
14193                    }
14194                    return;
14195                }
14196            }
14197            pw.println("No process found for: " + args[opti]);
14198            return;
14199        }
14200
14201        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14202            dumpDetails = true;
14203        }
14204
14205        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14206
14207        String[] innerArgs = new String[args.length-opti];
14208        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14209
14210        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14211        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14212        long nativePss = 0;
14213        long dalvikPss = 0;
14214        long otherPss = 0;
14215        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14216
14217        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14218        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14219                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14220
14221        long totalPss = 0;
14222        long cachedPss = 0;
14223
14224        Debug.MemoryInfo mi = null;
14225        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14226            final ProcessRecord r = procs.get(i);
14227            final IApplicationThread thread;
14228            final int pid;
14229            final int oomAdj;
14230            final boolean hasActivities;
14231            synchronized (this) {
14232                thread = r.thread;
14233                pid = r.pid;
14234                oomAdj = r.getSetAdjWithServices();
14235                hasActivities = r.activities.size() > 0;
14236            }
14237            if (thread != null) {
14238                if (!isCheckinRequest && dumpDetails) {
14239                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14240                }
14241                if (mi == null) {
14242                    mi = new Debug.MemoryInfo();
14243                }
14244                if (dumpDetails || (!brief && !oomOnly)) {
14245                    Debug.getMemoryInfo(pid, mi);
14246                } else {
14247                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14248                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14249                }
14250                if (dumpDetails) {
14251                    if (localOnly) {
14252                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14253                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14254                        if (isCheckinRequest) {
14255                            pw.println();
14256                        }
14257                    } else {
14258                        try {
14259                            pw.flush();
14260                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14261                                    dumpDalvik, innerArgs);
14262                        } catch (RemoteException e) {
14263                            if (!isCheckinRequest) {
14264                                pw.println("Got RemoteException!");
14265                                pw.flush();
14266                            }
14267                        }
14268                    }
14269                }
14270
14271                final long myTotalPss = mi.getTotalPss();
14272                final long myTotalUss = mi.getTotalUss();
14273
14274                synchronized (this) {
14275                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14276                        // Record this for posterity if the process has been stable.
14277                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14278                    }
14279                }
14280
14281                if (!isCheckinRequest && mi != null) {
14282                    totalPss += myTotalPss;
14283                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14284                            (hasActivities ? " / activities)" : ")"),
14285                            r.processName, myTotalPss, pid, hasActivities);
14286                    procMems.add(pssItem);
14287                    procMemsMap.put(pid, pssItem);
14288
14289                    nativePss += mi.nativePss;
14290                    dalvikPss += mi.dalvikPss;
14291                    otherPss += mi.otherPss;
14292                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14293                        long mem = mi.getOtherPss(j);
14294                        miscPss[j] += mem;
14295                        otherPss -= mem;
14296                    }
14297
14298                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14299                        cachedPss += myTotalPss;
14300                    }
14301
14302                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14303                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14304                                || oomIndex == (oomPss.length-1)) {
14305                            oomPss[oomIndex] += myTotalPss;
14306                            if (oomProcs[oomIndex] == null) {
14307                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14308                            }
14309                            oomProcs[oomIndex].add(pssItem);
14310                            break;
14311                        }
14312                    }
14313                }
14314            }
14315        }
14316
14317        long nativeProcTotalPss = 0;
14318
14319        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14320            // If we are showing aggregations, also look for native processes to
14321            // include so that our aggregations are more accurate.
14322            updateCpuStatsNow();
14323            mi = null;
14324            synchronized (mProcessCpuTracker) {
14325                final int N = mProcessCpuTracker.countStats();
14326                for (int i=0; i<N; i++) {
14327                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14328                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14329                        if (mi == null) {
14330                            mi = new Debug.MemoryInfo();
14331                        }
14332                        if (!brief && !oomOnly) {
14333                            Debug.getMemoryInfo(st.pid, mi);
14334                        } else {
14335                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14336                            mi.nativePrivateDirty = (int)tmpLong[0];
14337                        }
14338
14339                        final long myTotalPss = mi.getTotalPss();
14340                        totalPss += myTotalPss;
14341                        nativeProcTotalPss += myTotalPss;
14342
14343                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14344                                st.name, myTotalPss, st.pid, false);
14345                        procMems.add(pssItem);
14346
14347                        nativePss += mi.nativePss;
14348                        dalvikPss += mi.dalvikPss;
14349                        otherPss += mi.otherPss;
14350                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14351                            long mem = mi.getOtherPss(j);
14352                            miscPss[j] += mem;
14353                            otherPss -= mem;
14354                        }
14355                        oomPss[0] += myTotalPss;
14356                        if (oomProcs[0] == null) {
14357                            oomProcs[0] = new ArrayList<MemItem>();
14358                        }
14359                        oomProcs[0].add(pssItem);
14360                    }
14361                }
14362            }
14363
14364            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14365
14366            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14367            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14368            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14369            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14370                String label = Debug.MemoryInfo.getOtherLabel(j);
14371                catMems.add(new MemItem(label, label, miscPss[j], j));
14372            }
14373
14374            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14375            for (int j=0; j<oomPss.length; j++) {
14376                if (oomPss[j] != 0) {
14377                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14378                            : DUMP_MEM_OOM_LABEL[j];
14379                    MemItem item = new MemItem(label, label, oomPss[j],
14380                            DUMP_MEM_OOM_ADJ[j]);
14381                    item.subitems = oomProcs[j];
14382                    oomMems.add(item);
14383                }
14384            }
14385
14386            if (!brief && !oomOnly && !isCompact) {
14387                pw.println();
14388                pw.println("Total PSS by process:");
14389                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14390                pw.println();
14391            }
14392            if (!isCompact) {
14393                pw.println("Total PSS by OOM adjustment:");
14394            }
14395            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14396            if (!brief && !oomOnly) {
14397                PrintWriter out = categoryPw != null ? categoryPw : pw;
14398                if (!isCompact) {
14399                    out.println();
14400                    out.println("Total PSS by category:");
14401                }
14402                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14403            }
14404            if (!isCompact) {
14405                pw.println();
14406            }
14407            MemInfoReader memInfo = new MemInfoReader();
14408            memInfo.readMemInfo();
14409            if (nativeProcTotalPss > 0) {
14410                synchronized (this) {
14411                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14412                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14413                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14414                }
14415            }
14416            if (!brief) {
14417                if (!isCompact) {
14418                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14419                    pw.print(" kB (status ");
14420                    switch (mLastMemoryLevel) {
14421                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14422                            pw.println("normal)");
14423                            break;
14424                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14425                            pw.println("moderate)");
14426                            break;
14427                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14428                            pw.println("low)");
14429                            break;
14430                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14431                            pw.println("critical)");
14432                            break;
14433                        default:
14434                            pw.print(mLastMemoryLevel);
14435                            pw.println(")");
14436                            break;
14437                    }
14438                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14439                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14440                            pw.print(cachedPss); pw.print(" cached pss + ");
14441                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14442                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14443                } else {
14444                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14445                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14446                            + memInfo.getFreeSizeKb()); pw.print(",");
14447                    pw.println(totalPss - cachedPss);
14448                }
14449            }
14450            if (!isCompact) {
14451                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14452                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14453                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14454                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14455                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14456                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14457                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14458            }
14459            if (!brief) {
14460                if (memInfo.getZramTotalSizeKb() != 0) {
14461                    if (!isCompact) {
14462                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14463                                pw.print(" kB physical used for ");
14464                                pw.print(memInfo.getSwapTotalSizeKb()
14465                                        - memInfo.getSwapFreeSizeKb());
14466                                pw.print(" kB in swap (");
14467                                pw.print(memInfo.getSwapTotalSizeKb());
14468                                pw.println(" kB total swap)");
14469                    } else {
14470                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14471                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14472                                pw.println(memInfo.getSwapFreeSizeKb());
14473                    }
14474                }
14475                final long[] ksm = getKsmInfo();
14476                if (!isCompact) {
14477                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14478                            || ksm[KSM_VOLATILE] != 0) {
14479                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14480                                pw.print(" kB saved from shared ");
14481                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14482                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14483                                pw.print(" kB unshared; ");
14484                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14485                    }
14486                    pw.print("   Tuning: ");
14487                    pw.print(ActivityManager.staticGetMemoryClass());
14488                    pw.print(" (large ");
14489                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14490                    pw.print("), oom ");
14491                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14492                    pw.print(" kB");
14493                    pw.print(", restore limit ");
14494                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14495                    pw.print(" kB");
14496                    if (ActivityManager.isLowRamDeviceStatic()) {
14497                        pw.print(" (low-ram)");
14498                    }
14499                    if (ActivityManager.isHighEndGfx()) {
14500                        pw.print(" (high-end-gfx)");
14501                    }
14502                    pw.println();
14503                } else {
14504                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14505                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14506                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14507                    pw.print("tuning,");
14508                    pw.print(ActivityManager.staticGetMemoryClass());
14509                    pw.print(',');
14510                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14511                    pw.print(',');
14512                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14513                    if (ActivityManager.isLowRamDeviceStatic()) {
14514                        pw.print(",low-ram");
14515                    }
14516                    if (ActivityManager.isHighEndGfx()) {
14517                        pw.print(",high-end-gfx");
14518                    }
14519                    pw.println();
14520                }
14521            }
14522        }
14523    }
14524
14525    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14526            long memtrack, String name) {
14527        sb.append("  ");
14528        sb.append(ProcessList.makeOomAdjString(oomAdj));
14529        sb.append(' ');
14530        sb.append(ProcessList.makeProcStateString(procState));
14531        sb.append(' ');
14532        ProcessList.appendRamKb(sb, pss);
14533        sb.append(" kB: ");
14534        sb.append(name);
14535        if (memtrack > 0) {
14536            sb.append(" (");
14537            sb.append(memtrack);
14538            sb.append(" kB memtrack)");
14539        }
14540    }
14541
14542    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14543        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14544        sb.append(" (pid ");
14545        sb.append(mi.pid);
14546        sb.append(") ");
14547        sb.append(mi.adjType);
14548        sb.append('\n');
14549        if (mi.adjReason != null) {
14550            sb.append("                      ");
14551            sb.append(mi.adjReason);
14552            sb.append('\n');
14553        }
14554    }
14555
14556    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14557        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14558        for (int i=0, N=memInfos.size(); i<N; i++) {
14559            ProcessMemInfo mi = memInfos.get(i);
14560            infoMap.put(mi.pid, mi);
14561        }
14562        updateCpuStatsNow();
14563        long[] memtrackTmp = new long[1];
14564        synchronized (mProcessCpuTracker) {
14565            final int N = mProcessCpuTracker.countStats();
14566            for (int i=0; i<N; i++) {
14567                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14568                if (st.vsize > 0) {
14569                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14570                    if (pss > 0) {
14571                        if (infoMap.indexOfKey(st.pid) < 0) {
14572                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14573                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14574                            mi.pss = pss;
14575                            mi.memtrack = memtrackTmp[0];
14576                            memInfos.add(mi);
14577                        }
14578                    }
14579                }
14580            }
14581        }
14582
14583        long totalPss = 0;
14584        long totalMemtrack = 0;
14585        for (int i=0, N=memInfos.size(); i<N; i++) {
14586            ProcessMemInfo mi = memInfos.get(i);
14587            if (mi.pss == 0) {
14588                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14589                mi.memtrack = memtrackTmp[0];
14590            }
14591            totalPss += mi.pss;
14592            totalMemtrack += mi.memtrack;
14593        }
14594        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14595            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14596                if (lhs.oomAdj != rhs.oomAdj) {
14597                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14598                }
14599                if (lhs.pss != rhs.pss) {
14600                    return lhs.pss < rhs.pss ? 1 : -1;
14601                }
14602                return 0;
14603            }
14604        });
14605
14606        StringBuilder tag = new StringBuilder(128);
14607        StringBuilder stack = new StringBuilder(128);
14608        tag.append("Low on memory -- ");
14609        appendMemBucket(tag, totalPss, "total", false);
14610        appendMemBucket(stack, totalPss, "total", true);
14611
14612        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14613        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14614        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14615
14616        boolean firstLine = true;
14617        int lastOomAdj = Integer.MIN_VALUE;
14618        long extraNativeRam = 0;
14619        long extraNativeMemtrack = 0;
14620        long cachedPss = 0;
14621        for (int i=0, N=memInfos.size(); i<N; i++) {
14622            ProcessMemInfo mi = memInfos.get(i);
14623
14624            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14625                cachedPss += mi.pss;
14626            }
14627
14628            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14629                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14630                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14631                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14632                if (lastOomAdj != mi.oomAdj) {
14633                    lastOomAdj = mi.oomAdj;
14634                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14635                        tag.append(" / ");
14636                    }
14637                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14638                        if (firstLine) {
14639                            stack.append(":");
14640                            firstLine = false;
14641                        }
14642                        stack.append("\n\t at ");
14643                    } else {
14644                        stack.append("$");
14645                    }
14646                } else {
14647                    tag.append(" ");
14648                    stack.append("$");
14649                }
14650                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14651                    appendMemBucket(tag, mi.pss, mi.name, false);
14652                }
14653                appendMemBucket(stack, mi.pss, mi.name, true);
14654                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14655                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14656                    stack.append("(");
14657                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14658                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14659                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14660                            stack.append(":");
14661                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14662                        }
14663                    }
14664                    stack.append(")");
14665                }
14666            }
14667
14668            appendMemInfo(fullNativeBuilder, mi);
14669            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14670                // The short form only has native processes that are >= 512K.
14671                if (mi.pss >= 512) {
14672                    appendMemInfo(shortNativeBuilder, mi);
14673                } else {
14674                    extraNativeRam += mi.pss;
14675                    extraNativeMemtrack += mi.memtrack;
14676                }
14677            } else {
14678                // Short form has all other details, but if we have collected RAM
14679                // from smaller native processes let's dump a summary of that.
14680                if (extraNativeRam > 0) {
14681                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14682                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14683                    shortNativeBuilder.append('\n');
14684                    extraNativeRam = 0;
14685                }
14686                appendMemInfo(fullJavaBuilder, mi);
14687            }
14688        }
14689
14690        fullJavaBuilder.append("           ");
14691        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14692        fullJavaBuilder.append(" kB: TOTAL");
14693        if (totalMemtrack > 0) {
14694            fullJavaBuilder.append(" (");
14695            fullJavaBuilder.append(totalMemtrack);
14696            fullJavaBuilder.append(" kB memtrack)");
14697        } else {
14698        }
14699        fullJavaBuilder.append("\n");
14700
14701        MemInfoReader memInfo = new MemInfoReader();
14702        memInfo.readMemInfo();
14703        final long[] infos = memInfo.getRawInfo();
14704
14705        StringBuilder memInfoBuilder = new StringBuilder(1024);
14706        Debug.getMemInfo(infos);
14707        memInfoBuilder.append("  MemInfo: ");
14708        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14709        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14710        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14711        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14712        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14713        memInfoBuilder.append("           ");
14714        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14715        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14716        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14717        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14718        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14719            memInfoBuilder.append("  ZRAM: ");
14720            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14721            memInfoBuilder.append(" kB RAM, ");
14722            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14723            memInfoBuilder.append(" kB swap total, ");
14724            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14725            memInfoBuilder.append(" kB swap free\n");
14726        }
14727        final long[] ksm = getKsmInfo();
14728        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14729                || ksm[KSM_VOLATILE] != 0) {
14730            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14731            memInfoBuilder.append(" kB saved from shared ");
14732            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14733            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14734            memInfoBuilder.append(" kB unshared; ");
14735            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14736        }
14737        memInfoBuilder.append("  Free RAM: ");
14738        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14739                + memInfo.getFreeSizeKb());
14740        memInfoBuilder.append(" kB\n");
14741        memInfoBuilder.append("  Used RAM: ");
14742        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14743        memInfoBuilder.append(" kB\n");
14744        memInfoBuilder.append("  Lost RAM: ");
14745        memInfoBuilder.append(memInfo.getTotalSizeKb()
14746                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14747                - memInfo.getKernelUsedSizeKb());
14748        memInfoBuilder.append(" kB\n");
14749        Slog.i(TAG, "Low on memory:");
14750        Slog.i(TAG, shortNativeBuilder.toString());
14751        Slog.i(TAG, fullJavaBuilder.toString());
14752        Slog.i(TAG, memInfoBuilder.toString());
14753
14754        StringBuilder dropBuilder = new StringBuilder(1024);
14755        /*
14756        StringWriter oomSw = new StringWriter();
14757        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14758        StringWriter catSw = new StringWriter();
14759        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14760        String[] emptyArgs = new String[] { };
14761        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14762        oomPw.flush();
14763        String oomString = oomSw.toString();
14764        */
14765        dropBuilder.append("Low on memory:");
14766        dropBuilder.append(stack);
14767        dropBuilder.append('\n');
14768        dropBuilder.append(fullNativeBuilder);
14769        dropBuilder.append(fullJavaBuilder);
14770        dropBuilder.append('\n');
14771        dropBuilder.append(memInfoBuilder);
14772        dropBuilder.append('\n');
14773        /*
14774        dropBuilder.append(oomString);
14775        dropBuilder.append('\n');
14776        */
14777        StringWriter catSw = new StringWriter();
14778        synchronized (ActivityManagerService.this) {
14779            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14780            String[] emptyArgs = new String[] { };
14781            catPw.println();
14782            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14783            catPw.println();
14784            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14785                    false, false, null);
14786            catPw.println();
14787            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14788            catPw.flush();
14789        }
14790        dropBuilder.append(catSw.toString());
14791        addErrorToDropBox("lowmem", null, "system_server", null,
14792                null, tag.toString(), dropBuilder.toString(), null, null);
14793        //Slog.i(TAG, "Sent to dropbox:");
14794        //Slog.i(TAG, dropBuilder.toString());
14795        synchronized (ActivityManagerService.this) {
14796            long now = SystemClock.uptimeMillis();
14797            if (mLastMemUsageReportTime < now) {
14798                mLastMemUsageReportTime = now;
14799            }
14800        }
14801    }
14802
14803    /**
14804     * Searches array of arguments for the specified string
14805     * @param args array of argument strings
14806     * @param value value to search for
14807     * @return true if the value is contained in the array
14808     */
14809    private static boolean scanArgs(String[] args, String value) {
14810        if (args != null) {
14811            for (String arg : args) {
14812                if (value.equals(arg)) {
14813                    return true;
14814                }
14815            }
14816        }
14817        return false;
14818    }
14819
14820    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14821            ContentProviderRecord cpr, boolean always) {
14822        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14823
14824        if (!inLaunching || always) {
14825            synchronized (cpr) {
14826                cpr.launchingApp = null;
14827                cpr.notifyAll();
14828            }
14829            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14830            String names[] = cpr.info.authority.split(";");
14831            for (int j = 0; j < names.length; j++) {
14832                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14833            }
14834        }
14835
14836        for (int i=0; i<cpr.connections.size(); i++) {
14837            ContentProviderConnection conn = cpr.connections.get(i);
14838            if (conn.waiting) {
14839                // If this connection is waiting for the provider, then we don't
14840                // need to mess with its process unless we are always removing
14841                // or for some reason the provider is not currently launching.
14842                if (inLaunching && !always) {
14843                    continue;
14844                }
14845            }
14846            ProcessRecord capp = conn.client;
14847            conn.dead = true;
14848            if (conn.stableCount > 0) {
14849                if (!capp.persistent && capp.thread != null
14850                        && capp.pid != 0
14851                        && capp.pid != MY_PID) {
14852                    capp.kill("depends on provider "
14853                            + cpr.name.flattenToShortString()
14854                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14855                }
14856            } else if (capp.thread != null && conn.provider.provider != null) {
14857                try {
14858                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14859                } catch (RemoteException e) {
14860                }
14861                // In the protocol here, we don't expect the client to correctly
14862                // clean up this connection, we'll just remove it.
14863                cpr.connections.remove(i);
14864                if (conn.client.conProviders.remove(conn)) {
14865                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14866                }
14867            }
14868        }
14869
14870        if (inLaunching && always) {
14871            mLaunchingProviders.remove(cpr);
14872        }
14873        return inLaunching;
14874    }
14875
14876    /**
14877     * Main code for cleaning up a process when it has gone away.  This is
14878     * called both as a result of the process dying, or directly when stopping
14879     * a process when running in single process mode.
14880     *
14881     * @return Returns true if the given process has been restarted, so the
14882     * app that was passed in must remain on the process lists.
14883     */
14884    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14885            boolean restarting, boolean allowRestart, int index) {
14886        if (index >= 0) {
14887            removeLruProcessLocked(app);
14888            ProcessList.remove(app.pid);
14889        }
14890
14891        mProcessesToGc.remove(app);
14892        mPendingPssProcesses.remove(app);
14893
14894        // Dismiss any open dialogs.
14895        if (app.crashDialog != null && !app.forceCrashReport) {
14896            app.crashDialog.dismiss();
14897            app.crashDialog = null;
14898        }
14899        if (app.anrDialog != null) {
14900            app.anrDialog.dismiss();
14901            app.anrDialog = null;
14902        }
14903        if (app.waitDialog != null) {
14904            app.waitDialog.dismiss();
14905            app.waitDialog = null;
14906        }
14907
14908        app.crashing = false;
14909        app.notResponding = false;
14910
14911        app.resetPackageList(mProcessStats);
14912        app.unlinkDeathRecipient();
14913        app.makeInactive(mProcessStats);
14914        app.waitingToKill = null;
14915        app.forcingToForeground = null;
14916        updateProcessForegroundLocked(app, false, false);
14917        app.foregroundActivities = false;
14918        app.hasShownUi = false;
14919        app.treatLikeActivity = false;
14920        app.hasAboveClient = false;
14921        app.hasClientActivities = false;
14922
14923        mServices.killServicesLocked(app, allowRestart);
14924
14925        boolean restart = false;
14926
14927        // Remove published content providers.
14928        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14929            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14930            final boolean always = app.bad || !allowRestart;
14931            if (removeDyingProviderLocked(app, cpr, always) || always) {
14932                // We left the provider in the launching list, need to
14933                // restart it.
14934                restart = true;
14935            }
14936
14937            cpr.provider = null;
14938            cpr.proc = null;
14939        }
14940        app.pubProviders.clear();
14941
14942        // Take care of any launching providers waiting for this process.
14943        if (checkAppInLaunchingProvidersLocked(app, false)) {
14944            restart = true;
14945        }
14946
14947        // Unregister from connected content providers.
14948        if (!app.conProviders.isEmpty()) {
14949            for (int i=0; i<app.conProviders.size(); i++) {
14950                ContentProviderConnection conn = app.conProviders.get(i);
14951                conn.provider.connections.remove(conn);
14952                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14953                        conn.provider.name);
14954            }
14955            app.conProviders.clear();
14956        }
14957
14958        // At this point there may be remaining entries in mLaunchingProviders
14959        // where we were the only one waiting, so they are no longer of use.
14960        // Look for these and clean up if found.
14961        // XXX Commented out for now.  Trying to figure out a way to reproduce
14962        // the actual situation to identify what is actually going on.
14963        if (false) {
14964            for (int i=0; i<mLaunchingProviders.size(); i++) {
14965                ContentProviderRecord cpr = (ContentProviderRecord)
14966                        mLaunchingProviders.get(i);
14967                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14968                    synchronized (cpr) {
14969                        cpr.launchingApp = null;
14970                        cpr.notifyAll();
14971                    }
14972                }
14973            }
14974        }
14975
14976        skipCurrentReceiverLocked(app);
14977
14978        // Unregister any receivers.
14979        for (int i=app.receivers.size()-1; i>=0; i--) {
14980            removeReceiverLocked(app.receivers.valueAt(i));
14981        }
14982        app.receivers.clear();
14983
14984        // If the app is undergoing backup, tell the backup manager about it
14985        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14986            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14987                    + mBackupTarget.appInfo + " died during backup");
14988            try {
14989                IBackupManager bm = IBackupManager.Stub.asInterface(
14990                        ServiceManager.getService(Context.BACKUP_SERVICE));
14991                bm.agentDisconnected(app.info.packageName);
14992            } catch (RemoteException e) {
14993                // can't happen; backup manager is local
14994            }
14995        }
14996
14997        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14998            ProcessChangeItem item = mPendingProcessChanges.get(i);
14999            if (item.pid == app.pid) {
15000                mPendingProcessChanges.remove(i);
15001                mAvailProcessChanges.add(item);
15002            }
15003        }
15004        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15005
15006        // If the caller is restarting this app, then leave it in its
15007        // current lists and let the caller take care of it.
15008        if (restarting) {
15009            return false;
15010        }
15011
15012        if (!app.persistent || app.isolated) {
15013            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15014                    "Removing non-persistent process during cleanup: " + app);
15015            mProcessNames.remove(app.processName, app.uid);
15016            mIsolatedProcesses.remove(app.uid);
15017            if (mHeavyWeightProcess == app) {
15018                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15019                        mHeavyWeightProcess.userId, 0));
15020                mHeavyWeightProcess = null;
15021            }
15022        } else if (!app.removed) {
15023            // This app is persistent, so we need to keep its record around.
15024            // If it is not already on the pending app list, add it there
15025            // and start a new process for it.
15026            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15027                mPersistentStartingProcesses.add(app);
15028                restart = true;
15029            }
15030        }
15031        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15032                "Clean-up removing on hold: " + app);
15033        mProcessesOnHold.remove(app);
15034
15035        if (app == mHomeProcess) {
15036            mHomeProcess = null;
15037        }
15038        if (app == mPreviousProcess) {
15039            mPreviousProcess = null;
15040        }
15041
15042        if (restart && !app.isolated) {
15043            // We have components that still need to be running in the
15044            // process, so re-launch it.
15045            if (index < 0) {
15046                ProcessList.remove(app.pid);
15047            }
15048            mProcessNames.put(app.processName, app.uid, app);
15049            startProcessLocked(app, "restart", app.processName);
15050            return true;
15051        } else if (app.pid > 0 && app.pid != MY_PID) {
15052            // Goodbye!
15053            boolean removed;
15054            synchronized (mPidsSelfLocked) {
15055                mPidsSelfLocked.remove(app.pid);
15056                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15057            }
15058            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15059            if (app.isolated) {
15060                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15061            }
15062            app.setPid(0);
15063        }
15064        return false;
15065    }
15066
15067    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15068        // Look through the content providers we are waiting to have launched,
15069        // and if any run in this process then either schedule a restart of
15070        // the process or kill the client waiting for it if this process has
15071        // gone bad.
15072        int NL = mLaunchingProviders.size();
15073        boolean restart = false;
15074        for (int i=0; i<NL; i++) {
15075            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15076            if (cpr.launchingApp == app) {
15077                if (!alwaysBad && !app.bad) {
15078                    restart = true;
15079                } else {
15080                    removeDyingProviderLocked(app, cpr, true);
15081                    // cpr should have been removed from mLaunchingProviders
15082                    NL = mLaunchingProviders.size();
15083                    i--;
15084                }
15085            }
15086        }
15087        return restart;
15088    }
15089
15090    // =========================================================
15091    // SERVICES
15092    // =========================================================
15093
15094    @Override
15095    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15096            int flags) {
15097        enforceNotIsolatedCaller("getServices");
15098        synchronized (this) {
15099            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15100        }
15101    }
15102
15103    @Override
15104    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15105        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15106        synchronized (this) {
15107            return mServices.getRunningServiceControlPanelLocked(name);
15108        }
15109    }
15110
15111    @Override
15112    public ComponentName startService(IApplicationThread caller, Intent service,
15113            String resolvedType, int userId) {
15114        enforceNotIsolatedCaller("startService");
15115        // Refuse possible leaked file descriptors
15116        if (service != null && service.hasFileDescriptors() == true) {
15117            throw new IllegalArgumentException("File descriptors passed in Intent");
15118        }
15119
15120        if (DEBUG_SERVICE)
15121            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15122        synchronized(this) {
15123            final int callingPid = Binder.getCallingPid();
15124            final int callingUid = Binder.getCallingUid();
15125            final long origId = Binder.clearCallingIdentity();
15126            ComponentName res = mServices.startServiceLocked(caller, service,
15127                    resolvedType, callingPid, callingUid, userId);
15128            Binder.restoreCallingIdentity(origId);
15129            return res;
15130        }
15131    }
15132
15133    ComponentName startServiceInPackage(int uid,
15134            Intent service, String resolvedType, int userId) {
15135        synchronized(this) {
15136            if (DEBUG_SERVICE)
15137                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15138            final long origId = Binder.clearCallingIdentity();
15139            ComponentName res = mServices.startServiceLocked(null, service,
15140                    resolvedType, -1, uid, userId);
15141            Binder.restoreCallingIdentity(origId);
15142            return res;
15143        }
15144    }
15145
15146    @Override
15147    public int stopService(IApplicationThread caller, Intent service,
15148            String resolvedType, int userId) {
15149        enforceNotIsolatedCaller("stopService");
15150        // Refuse possible leaked file descriptors
15151        if (service != null && service.hasFileDescriptors() == true) {
15152            throw new IllegalArgumentException("File descriptors passed in Intent");
15153        }
15154
15155        synchronized(this) {
15156            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15157        }
15158    }
15159
15160    @Override
15161    public IBinder peekService(Intent service, String resolvedType) {
15162        enforceNotIsolatedCaller("peekService");
15163        // Refuse possible leaked file descriptors
15164        if (service != null && service.hasFileDescriptors() == true) {
15165            throw new IllegalArgumentException("File descriptors passed in Intent");
15166        }
15167        synchronized(this) {
15168            return mServices.peekServiceLocked(service, resolvedType);
15169        }
15170    }
15171
15172    @Override
15173    public boolean stopServiceToken(ComponentName className, IBinder token,
15174            int startId) {
15175        synchronized(this) {
15176            return mServices.stopServiceTokenLocked(className, token, startId);
15177        }
15178    }
15179
15180    @Override
15181    public void setServiceForeground(ComponentName className, IBinder token,
15182            int id, Notification notification, boolean removeNotification) {
15183        synchronized(this) {
15184            mServices.setServiceForegroundLocked(className, token, id, notification,
15185                    removeNotification);
15186        }
15187    }
15188
15189    @Override
15190    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15191            boolean requireFull, String name, String callerPackage) {
15192        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15193                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15194    }
15195
15196    int unsafeConvertIncomingUser(int userId) {
15197        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15198                ? mCurrentUserId : userId;
15199    }
15200
15201    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15202            int allowMode, String name, String callerPackage) {
15203        final int callingUserId = UserHandle.getUserId(callingUid);
15204        if (callingUserId == userId) {
15205            return userId;
15206        }
15207
15208        // Note that we may be accessing mCurrentUserId outside of a lock...
15209        // shouldn't be a big deal, if this is being called outside
15210        // of a locked context there is intrinsically a race with
15211        // the value the caller will receive and someone else changing it.
15212        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15213        // we will switch to the calling user if access to the current user fails.
15214        int targetUserId = unsafeConvertIncomingUser(userId);
15215
15216        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15217            final boolean allow;
15218            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15219                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15220                // If the caller has this permission, they always pass go.  And collect $200.
15221                allow = true;
15222            } else if (allowMode == ALLOW_FULL_ONLY) {
15223                // We require full access, sucks to be you.
15224                allow = false;
15225            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15226                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15227                // If the caller does not have either permission, they are always doomed.
15228                allow = false;
15229            } else if (allowMode == ALLOW_NON_FULL) {
15230                // We are blanket allowing non-full access, you lucky caller!
15231                allow = true;
15232            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15233                // We may or may not allow this depending on whether the two users are
15234                // in the same profile.
15235                synchronized (mUserProfileGroupIdsSelfLocked) {
15236                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15237                            UserInfo.NO_PROFILE_GROUP_ID);
15238                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15239                            UserInfo.NO_PROFILE_GROUP_ID);
15240                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15241                            && callingProfile == targetProfile;
15242                }
15243            } else {
15244                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15245            }
15246            if (!allow) {
15247                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15248                    // In this case, they would like to just execute as their
15249                    // owner user instead of failing.
15250                    targetUserId = callingUserId;
15251                } else {
15252                    StringBuilder builder = new StringBuilder(128);
15253                    builder.append("Permission Denial: ");
15254                    builder.append(name);
15255                    if (callerPackage != null) {
15256                        builder.append(" from ");
15257                        builder.append(callerPackage);
15258                    }
15259                    builder.append(" asks to run as user ");
15260                    builder.append(userId);
15261                    builder.append(" but is calling from user ");
15262                    builder.append(UserHandle.getUserId(callingUid));
15263                    builder.append("; this requires ");
15264                    builder.append(INTERACT_ACROSS_USERS_FULL);
15265                    if (allowMode != ALLOW_FULL_ONLY) {
15266                        builder.append(" or ");
15267                        builder.append(INTERACT_ACROSS_USERS);
15268                    }
15269                    String msg = builder.toString();
15270                    Slog.w(TAG, msg);
15271                    throw new SecurityException(msg);
15272                }
15273            }
15274        }
15275        if (!allowAll && targetUserId < 0) {
15276            throw new IllegalArgumentException(
15277                    "Call does not support special user #" + targetUserId);
15278        }
15279        // Check shell permission
15280        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15281            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15282                    targetUserId)) {
15283                throw new SecurityException("Shell does not have permission to access user "
15284                        + targetUserId + "\n " + Debug.getCallers(3));
15285            }
15286        }
15287        return targetUserId;
15288    }
15289
15290    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15291            String className, int flags) {
15292        boolean result = false;
15293        // For apps that don't have pre-defined UIDs, check for permission
15294        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15295            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15296                if (ActivityManager.checkUidPermission(
15297                        INTERACT_ACROSS_USERS,
15298                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15299                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15300                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15301                            + " requests FLAG_SINGLE_USER, but app does not hold "
15302                            + INTERACT_ACROSS_USERS;
15303                    Slog.w(TAG, msg);
15304                    throw new SecurityException(msg);
15305                }
15306                // Permission passed
15307                result = true;
15308            }
15309        } else if ("system".equals(componentProcessName)) {
15310            result = true;
15311        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15312            // Phone app and persistent apps are allowed to export singleuser providers.
15313            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15314                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15315        }
15316        if (DEBUG_MU) {
15317            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15318                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15319        }
15320        return result;
15321    }
15322
15323    /**
15324     * Checks to see if the caller is in the same app as the singleton
15325     * component, or the component is in a special app. It allows special apps
15326     * to export singleton components but prevents exporting singleton
15327     * components for regular apps.
15328     */
15329    boolean isValidSingletonCall(int callingUid, int componentUid) {
15330        int componentAppId = UserHandle.getAppId(componentUid);
15331        return UserHandle.isSameApp(callingUid, componentUid)
15332                || componentAppId == Process.SYSTEM_UID
15333                || componentAppId == Process.PHONE_UID
15334                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15335                        == PackageManager.PERMISSION_GRANTED;
15336    }
15337
15338    public int bindService(IApplicationThread caller, IBinder token,
15339            Intent service, String resolvedType,
15340            IServiceConnection connection, int flags, int userId) {
15341        enforceNotIsolatedCaller("bindService");
15342
15343        // Refuse possible leaked file descriptors
15344        if (service != null && service.hasFileDescriptors() == true) {
15345            throw new IllegalArgumentException("File descriptors passed in Intent");
15346        }
15347
15348        synchronized(this) {
15349            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15350                    connection, flags, userId);
15351        }
15352    }
15353
15354    public boolean unbindService(IServiceConnection connection) {
15355        synchronized (this) {
15356            return mServices.unbindServiceLocked(connection);
15357        }
15358    }
15359
15360    public void publishService(IBinder token, Intent intent, IBinder service) {
15361        // Refuse possible leaked file descriptors
15362        if (intent != null && intent.hasFileDescriptors() == true) {
15363            throw new IllegalArgumentException("File descriptors passed in Intent");
15364        }
15365
15366        synchronized(this) {
15367            if (!(token instanceof ServiceRecord)) {
15368                throw new IllegalArgumentException("Invalid service token");
15369            }
15370            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15371        }
15372    }
15373
15374    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15375        // Refuse possible leaked file descriptors
15376        if (intent != null && intent.hasFileDescriptors() == true) {
15377            throw new IllegalArgumentException("File descriptors passed in Intent");
15378        }
15379
15380        synchronized(this) {
15381            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15382        }
15383    }
15384
15385    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15386        synchronized(this) {
15387            if (!(token instanceof ServiceRecord)) {
15388                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15389                throw new IllegalArgumentException("Invalid service token");
15390            }
15391            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15392        }
15393    }
15394
15395    // =========================================================
15396    // BACKUP AND RESTORE
15397    // =========================================================
15398
15399    // Cause the target app to be launched if necessary and its backup agent
15400    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15401    // activity manager to announce its creation.
15402    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15403        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15404        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15405
15406        synchronized(this) {
15407            // !!! TODO: currently no check here that we're already bound
15408            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15409            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15410            synchronized (stats) {
15411                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15412            }
15413
15414            // Backup agent is now in use, its package can't be stopped.
15415            try {
15416                AppGlobals.getPackageManager().setPackageStoppedState(
15417                        app.packageName, false, UserHandle.getUserId(app.uid));
15418            } catch (RemoteException e) {
15419            } catch (IllegalArgumentException e) {
15420                Slog.w(TAG, "Failed trying to unstop package "
15421                        + app.packageName + ": " + e);
15422            }
15423
15424            BackupRecord r = new BackupRecord(ss, app, backupMode);
15425            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15426                    ? new ComponentName(app.packageName, app.backupAgentName)
15427                    : new ComponentName("android", "FullBackupAgent");
15428            // startProcessLocked() returns existing proc's record if it's already running
15429            ProcessRecord proc = startProcessLocked(app.processName, app,
15430                    false, 0, "backup", hostingName, false, false, false);
15431            if (proc == null) {
15432                Slog.e(TAG, "Unable to start backup agent process " + r);
15433                return false;
15434            }
15435
15436            r.app = proc;
15437            mBackupTarget = r;
15438            mBackupAppName = app.packageName;
15439
15440            // Try not to kill the process during backup
15441            updateOomAdjLocked(proc);
15442
15443            // If the process is already attached, schedule the creation of the backup agent now.
15444            // If it is not yet live, this will be done when it attaches to the framework.
15445            if (proc.thread != null) {
15446                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15447                try {
15448                    proc.thread.scheduleCreateBackupAgent(app,
15449                            compatibilityInfoForPackageLocked(app), backupMode);
15450                } catch (RemoteException e) {
15451                    // Will time out on the backup manager side
15452                }
15453            } else {
15454                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15455            }
15456            // Invariants: at this point, the target app process exists and the application
15457            // is either already running or in the process of coming up.  mBackupTarget and
15458            // mBackupAppName describe the app, so that when it binds back to the AM we
15459            // know that it's scheduled for a backup-agent operation.
15460        }
15461
15462        return true;
15463    }
15464
15465    @Override
15466    public void clearPendingBackup() {
15467        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15468        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15469
15470        synchronized (this) {
15471            mBackupTarget = null;
15472            mBackupAppName = null;
15473        }
15474    }
15475
15476    // A backup agent has just come up
15477    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15478        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15479                + " = " + agent);
15480
15481        synchronized(this) {
15482            if (!agentPackageName.equals(mBackupAppName)) {
15483                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15484                return;
15485            }
15486        }
15487
15488        long oldIdent = Binder.clearCallingIdentity();
15489        try {
15490            IBackupManager bm = IBackupManager.Stub.asInterface(
15491                    ServiceManager.getService(Context.BACKUP_SERVICE));
15492            bm.agentConnected(agentPackageName, agent);
15493        } catch (RemoteException e) {
15494            // can't happen; the backup manager service is local
15495        } catch (Exception e) {
15496            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15497            e.printStackTrace();
15498        } finally {
15499            Binder.restoreCallingIdentity(oldIdent);
15500        }
15501    }
15502
15503    // done with this agent
15504    public void unbindBackupAgent(ApplicationInfo appInfo) {
15505        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15506        if (appInfo == null) {
15507            Slog.w(TAG, "unbind backup agent for null app");
15508            return;
15509        }
15510
15511        synchronized(this) {
15512            try {
15513                if (mBackupAppName == null) {
15514                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15515                    return;
15516                }
15517
15518                if (!mBackupAppName.equals(appInfo.packageName)) {
15519                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15520                    return;
15521                }
15522
15523                // Not backing this app up any more; reset its OOM adjustment
15524                final ProcessRecord proc = mBackupTarget.app;
15525                updateOomAdjLocked(proc);
15526
15527                // If the app crashed during backup, 'thread' will be null here
15528                if (proc.thread != null) {
15529                    try {
15530                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15531                                compatibilityInfoForPackageLocked(appInfo));
15532                    } catch (Exception e) {
15533                        Slog.e(TAG, "Exception when unbinding backup agent:");
15534                        e.printStackTrace();
15535                    }
15536                }
15537            } finally {
15538                mBackupTarget = null;
15539                mBackupAppName = null;
15540            }
15541        }
15542    }
15543    // =========================================================
15544    // BROADCASTS
15545    // =========================================================
15546
15547    boolean isPendingBroadcastProcessLocked(int pid) {
15548        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15549                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15550    }
15551
15552    void skipPendingBroadcastLocked(int pid) {
15553            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15554            for (BroadcastQueue queue : mBroadcastQueues) {
15555                queue.skipPendingBroadcastLocked(pid);
15556            }
15557    }
15558
15559    // The app just attached; send any pending broadcasts that it should receive
15560    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15561        boolean didSomething = false;
15562        for (BroadcastQueue queue : mBroadcastQueues) {
15563            didSomething |= queue.sendPendingBroadcastsLocked(app);
15564        }
15565        return didSomething;
15566    }
15567
15568    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15569            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15570        enforceNotIsolatedCaller("registerReceiver");
15571        ArrayList<Intent> stickyIntents = null;
15572        ProcessRecord callerApp = null;
15573        int callingUid;
15574        int callingPid;
15575        synchronized(this) {
15576            if (caller != null) {
15577                callerApp = getRecordForAppLocked(caller);
15578                if (callerApp == null) {
15579                    throw new SecurityException(
15580                            "Unable to find app for caller " + caller
15581                            + " (pid=" + Binder.getCallingPid()
15582                            + ") when registering receiver " + receiver);
15583                }
15584                if (callerApp.info.uid != Process.SYSTEM_UID &&
15585                        !callerApp.pkgList.containsKey(callerPackage) &&
15586                        !"android".equals(callerPackage)) {
15587                    throw new SecurityException("Given caller package " + callerPackage
15588                            + " is not running in process " + callerApp);
15589                }
15590                callingUid = callerApp.info.uid;
15591                callingPid = callerApp.pid;
15592            } else {
15593                callerPackage = null;
15594                callingUid = Binder.getCallingUid();
15595                callingPid = Binder.getCallingPid();
15596            }
15597
15598            userId = handleIncomingUser(callingPid, callingUid, userId,
15599                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15600
15601            Iterator<String> actions = filter.actionsIterator();
15602            if (actions == null) {
15603                ArrayList<String> noAction = new ArrayList<String>(1);
15604                noAction.add(null);
15605                actions = noAction.iterator();
15606            }
15607
15608            // Collect stickies of users
15609            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15610            while (actions.hasNext()) {
15611                String action = actions.next();
15612                for (int id : userIds) {
15613                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15614                    if (stickies != null) {
15615                        ArrayList<Intent> intents = stickies.get(action);
15616                        if (intents != null) {
15617                            if (stickyIntents == null) {
15618                                stickyIntents = new ArrayList<Intent>();
15619                            }
15620                            stickyIntents.addAll(intents);
15621                        }
15622                    }
15623                }
15624            }
15625        }
15626
15627        ArrayList<Intent> allSticky = null;
15628        if (stickyIntents != null) {
15629            final ContentResolver resolver = mContext.getContentResolver();
15630            // Look for any matching sticky broadcasts...
15631            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15632                Intent intent = stickyIntents.get(i);
15633                // If intent has scheme "content", it will need to acccess
15634                // provider that needs to lock mProviderMap in ActivityThread
15635                // and also it may need to wait application response, so we
15636                // cannot lock ActivityManagerService here.
15637                if (filter.match(resolver, intent, true, TAG) >= 0) {
15638                    if (allSticky == null) {
15639                        allSticky = new ArrayList<Intent>();
15640                    }
15641                    allSticky.add(intent);
15642                }
15643            }
15644        }
15645
15646        // The first sticky in the list is returned directly back to the client.
15647        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15648        if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
15649        if (receiver == null) {
15650            return sticky;
15651        }
15652
15653        synchronized (this) {
15654            if (callerApp != null && callerApp.pid == 0) {
15655                // Caller already died
15656                return null;
15657            }
15658            ReceiverList rl
15659                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15660            if (rl == null) {
15661                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15662                        userId, receiver);
15663                if (rl.app != null) {
15664                    rl.app.receivers.add(rl);
15665                } else {
15666                    try {
15667                        receiver.asBinder().linkToDeath(rl, 0);
15668                    } catch (RemoteException e) {
15669                        return sticky;
15670                    }
15671                    rl.linkedToDeath = true;
15672                }
15673                mRegisteredReceivers.put(receiver.asBinder(), rl);
15674            } else if (rl.uid != callingUid) {
15675                throw new IllegalArgumentException(
15676                        "Receiver requested to register for uid " + callingUid
15677                        + " was previously registered for uid " + rl.uid);
15678            } else if (rl.pid != callingPid) {
15679                throw new IllegalArgumentException(
15680                        "Receiver requested to register for pid " + callingPid
15681                        + " was previously registered for pid " + rl.pid);
15682            } else if (rl.userId != userId) {
15683                throw new IllegalArgumentException(
15684                        "Receiver requested to register for user " + userId
15685                        + " was previously registered for user " + rl.userId);
15686            }
15687            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15688                    permission, callingUid, userId);
15689            rl.add(bf);
15690            if (!bf.debugCheck()) {
15691                Slog.w(TAG, "==> For Dynamic broadast");
15692            }
15693            mReceiverResolver.addFilter(bf);
15694
15695            // Enqueue broadcasts for all existing stickies that match
15696            // this filter.
15697            if (allSticky != null) {
15698                ArrayList receivers = new ArrayList();
15699                receivers.add(bf);
15700
15701                int N = allSticky.size();
15702                for (int i=0; i<N; i++) {
15703                    Intent intent = (Intent)allSticky.get(i);
15704                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15705                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15706                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15707                            null, null, false, true, true, -1);
15708                    queue.enqueueParallelBroadcastLocked(r);
15709                    queue.scheduleBroadcastsLocked();
15710                }
15711            }
15712
15713            return sticky;
15714        }
15715    }
15716
15717    public void unregisterReceiver(IIntentReceiver receiver) {
15718        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15719
15720        final long origId = Binder.clearCallingIdentity();
15721        try {
15722            boolean doTrim = false;
15723
15724            synchronized(this) {
15725                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15726                if (rl != null) {
15727                    final BroadcastRecord r = rl.curBroadcast;
15728                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15729                        final boolean doNext = r.queue.finishReceiverLocked(
15730                                r, r.resultCode, r.resultData, r.resultExtras,
15731                                r.resultAbort, false);
15732                        if (doNext) {
15733                            doTrim = true;
15734                            r.queue.processNextBroadcast(false);
15735                        }
15736                    }
15737
15738                    if (rl.app != null) {
15739                        rl.app.receivers.remove(rl);
15740                    }
15741                    removeReceiverLocked(rl);
15742                    if (rl.linkedToDeath) {
15743                        rl.linkedToDeath = false;
15744                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15745                    }
15746                }
15747            }
15748
15749            // If we actually concluded any broadcasts, we might now be able
15750            // to trim the recipients' apps from our working set
15751            if (doTrim) {
15752                trimApplications();
15753                return;
15754            }
15755
15756        } finally {
15757            Binder.restoreCallingIdentity(origId);
15758        }
15759    }
15760
15761    void removeReceiverLocked(ReceiverList rl) {
15762        mRegisteredReceivers.remove(rl.receiver.asBinder());
15763        int N = rl.size();
15764        for (int i=0; i<N; i++) {
15765            mReceiverResolver.removeFilter(rl.get(i));
15766        }
15767    }
15768
15769    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15770        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15771            ProcessRecord r = mLruProcesses.get(i);
15772            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15773                try {
15774                    r.thread.dispatchPackageBroadcast(cmd, packages);
15775                } catch (RemoteException ex) {
15776                }
15777            }
15778        }
15779    }
15780
15781    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15782            int callingUid, int[] users) {
15783        List<ResolveInfo> receivers = null;
15784        try {
15785            HashSet<ComponentName> singleUserReceivers = null;
15786            boolean scannedFirstReceivers = false;
15787            for (int user : users) {
15788                // Skip users that have Shell restrictions
15789                if (callingUid == Process.SHELL_UID
15790                        && getUserManagerLocked().hasUserRestriction(
15791                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15792                    continue;
15793                }
15794                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15795                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15796                if (user != 0 && newReceivers != null) {
15797                    // If this is not the primary user, we need to check for
15798                    // any receivers that should be filtered out.
15799                    for (int i=0; i<newReceivers.size(); i++) {
15800                        ResolveInfo ri = newReceivers.get(i);
15801                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15802                            newReceivers.remove(i);
15803                            i--;
15804                        }
15805                    }
15806                }
15807                if (newReceivers != null && newReceivers.size() == 0) {
15808                    newReceivers = null;
15809                }
15810                if (receivers == null) {
15811                    receivers = newReceivers;
15812                } else if (newReceivers != null) {
15813                    // We need to concatenate the additional receivers
15814                    // found with what we have do far.  This would be easy,
15815                    // but we also need to de-dup any receivers that are
15816                    // singleUser.
15817                    if (!scannedFirstReceivers) {
15818                        // Collect any single user receivers we had already retrieved.
15819                        scannedFirstReceivers = true;
15820                        for (int i=0; i<receivers.size(); i++) {
15821                            ResolveInfo ri = receivers.get(i);
15822                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15823                                ComponentName cn = new ComponentName(
15824                                        ri.activityInfo.packageName, ri.activityInfo.name);
15825                                if (singleUserReceivers == null) {
15826                                    singleUserReceivers = new HashSet<ComponentName>();
15827                                }
15828                                singleUserReceivers.add(cn);
15829                            }
15830                        }
15831                    }
15832                    // Add the new results to the existing results, tracking
15833                    // and de-dupping single user receivers.
15834                    for (int i=0; i<newReceivers.size(); i++) {
15835                        ResolveInfo ri = newReceivers.get(i);
15836                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15837                            ComponentName cn = new ComponentName(
15838                                    ri.activityInfo.packageName, ri.activityInfo.name);
15839                            if (singleUserReceivers == null) {
15840                                singleUserReceivers = new HashSet<ComponentName>();
15841                            }
15842                            if (!singleUserReceivers.contains(cn)) {
15843                                singleUserReceivers.add(cn);
15844                                receivers.add(ri);
15845                            }
15846                        } else {
15847                            receivers.add(ri);
15848                        }
15849                    }
15850                }
15851            }
15852        } catch (RemoteException ex) {
15853            // pm is in same process, this will never happen.
15854        }
15855        return receivers;
15856    }
15857
15858    private final int broadcastIntentLocked(ProcessRecord callerApp,
15859            String callerPackage, Intent intent, String resolvedType,
15860            IIntentReceiver resultTo, int resultCode, String resultData,
15861            Bundle map, String requiredPermission, int appOp,
15862            boolean ordered, boolean sticky, int callingPid, int callingUid,
15863            int userId) {
15864        intent = new Intent(intent);
15865
15866        // By default broadcasts do not go to stopped apps.
15867        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15868
15869        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15870            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15871            + " ordered=" + ordered + " userid=" + userId);
15872        if ((resultTo != null) && !ordered) {
15873            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15874        }
15875
15876        userId = handleIncomingUser(callingPid, callingUid, userId,
15877                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15878
15879        // Make sure that the user who is receiving this broadcast is running.
15880        // If not, we will just skip it. Make an exception for shutdown broadcasts
15881        // and upgrade steps.
15882
15883        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15884            if ((callingUid != Process.SYSTEM_UID
15885                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15886                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15887                Slog.w(TAG, "Skipping broadcast of " + intent
15888                        + ": user " + userId + " is stopped");
15889                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15890            }
15891        }
15892
15893        /*
15894         * Prevent non-system code (defined here to be non-persistent
15895         * processes) from sending protected broadcasts.
15896         */
15897        int callingAppId = UserHandle.getAppId(callingUid);
15898        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15899            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15900            || callingAppId == Process.NFC_UID || callingUid == 0) {
15901            // Always okay.
15902        } else if (callerApp == null || !callerApp.persistent) {
15903            try {
15904                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15905                        intent.getAction())) {
15906                    String msg = "Permission Denial: not allowed to send broadcast "
15907                            + intent.getAction() + " from pid="
15908                            + callingPid + ", uid=" + callingUid;
15909                    Slog.w(TAG, msg);
15910                    throw new SecurityException(msg);
15911                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15912                    // Special case for compatibility: we don't want apps to send this,
15913                    // but historically it has not been protected and apps may be using it
15914                    // to poke their own app widget.  So, instead of making it protected,
15915                    // just limit it to the caller.
15916                    if (callerApp == null) {
15917                        String msg = "Permission Denial: not allowed to send broadcast "
15918                                + intent.getAction() + " from unknown caller.";
15919                        Slog.w(TAG, msg);
15920                        throw new SecurityException(msg);
15921                    } else if (intent.getComponent() != null) {
15922                        // They are good enough to send to an explicit component...  verify
15923                        // it is being sent to the calling app.
15924                        if (!intent.getComponent().getPackageName().equals(
15925                                callerApp.info.packageName)) {
15926                            String msg = "Permission Denial: not allowed to send broadcast "
15927                                    + intent.getAction() + " to "
15928                                    + intent.getComponent().getPackageName() + " from "
15929                                    + callerApp.info.packageName;
15930                            Slog.w(TAG, msg);
15931                            throw new SecurityException(msg);
15932                        }
15933                    } else {
15934                        // Limit broadcast to their own package.
15935                        intent.setPackage(callerApp.info.packageName);
15936                    }
15937                }
15938            } catch (RemoteException e) {
15939                Slog.w(TAG, "Remote exception", e);
15940                return ActivityManager.BROADCAST_SUCCESS;
15941            }
15942        }
15943
15944        final String action = intent.getAction();
15945        if (action != null) {
15946            switch (action) {
15947                case Intent.ACTION_UID_REMOVED:
15948                case Intent.ACTION_PACKAGE_REMOVED:
15949                case Intent.ACTION_PACKAGE_CHANGED:
15950                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15951                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15952                    // Handle special intents: if this broadcast is from the package
15953                    // manager about a package being removed, we need to remove all of
15954                    // its activities from the history stack.
15955                    if (checkComponentPermission(
15956                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15957                            callingPid, callingUid, -1, true)
15958                            != PackageManager.PERMISSION_GRANTED) {
15959                        String msg = "Permission Denial: " + intent.getAction()
15960                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15961                                + ", uid=" + callingUid + ")"
15962                                + " requires "
15963                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15964                        Slog.w(TAG, msg);
15965                        throw new SecurityException(msg);
15966                    }
15967                    switch (action) {
15968                        case Intent.ACTION_UID_REMOVED:
15969                            final Bundle intentExtras = intent.getExtras();
15970                            final int uid = intentExtras != null
15971                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15972                            if (uid >= 0) {
15973                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15974                                synchronized (bs) {
15975                                    bs.removeUidStatsLocked(uid);
15976                                }
15977                                mAppOpsService.uidRemoved(uid);
15978                            }
15979                            break;
15980                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15981                            // If resources are unavailable just force stop all those packages
15982                            // and flush the attribute cache as well.
15983                            String list[] =
15984                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15985                            if (list != null && list.length > 0) {
15986                                for (int i = 0; i < list.length; i++) {
15987                                    forceStopPackageLocked(list[i], -1, false, true, true,
15988                                            false, false, userId, "storage unmount");
15989                                }
15990                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15991                                sendPackageBroadcastLocked(
15992                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15993                                        userId);
15994                            }
15995                            break;
15996                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15997                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15998                            break;
15999                        case Intent.ACTION_PACKAGE_REMOVED:
16000                        case Intent.ACTION_PACKAGE_CHANGED:
16001                            Uri data = intent.getData();
16002                            String ssp;
16003                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16004                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16005                                boolean fullUninstall = removed &&
16006                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16007                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16008                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16009                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16010                                            false, true, true, false, fullUninstall, userId,
16011                                            removed ? "pkg removed" : "pkg changed");
16012                                }
16013                                if (removed) {
16014                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16015                                            new String[] {ssp}, userId);
16016                                    if (fullUninstall) {
16017                                        mAppOpsService.packageRemoved(
16018                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16019
16020                                        // Remove all permissions granted from/to this package
16021                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16022
16023                                        removeTasksByPackageNameLocked(ssp, userId);
16024                                        if (userId == UserHandle.USER_OWNER) {
16025                                            mTaskPersister.removeFromPackageCache(ssp);
16026                                        }
16027                                    }
16028                                } else {
16029                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16030                                    if (userId == UserHandle.USER_OWNER) {
16031                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16032                                    }
16033                                }
16034                            }
16035                            break;
16036                    }
16037                    break;
16038                case Intent.ACTION_PACKAGE_ADDED:
16039                    // Special case for adding a package: by default turn on compatibility mode.
16040                    Uri data = intent.getData();
16041                    String ssp;
16042                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16043                        final boolean replacing =
16044                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16045                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16046
16047                        if (replacing) {
16048                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16049                        }
16050                        if (userId == UserHandle.USER_OWNER) {
16051                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16052                        }
16053                    }
16054                    break;
16055                case Intent.ACTION_TIMEZONE_CHANGED:
16056                    // If this is the time zone changed action, queue up a message that will reset
16057                    // the timezone of all currently running processes. This message will get
16058                    // queued up before the broadcast happens.
16059                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16060                    break;
16061                case Intent.ACTION_TIME_CHANGED:
16062                    // If the user set the time, let all running processes know.
16063                    final int is24Hour =
16064                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16065                                    : 0;
16066                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16067                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16068                    synchronized (stats) {
16069                        stats.noteCurrentTimeChangedLocked();
16070                    }
16071                    break;
16072                case Intent.ACTION_CLEAR_DNS_CACHE:
16073                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16074                    break;
16075                case Proxy.PROXY_CHANGE_ACTION:
16076                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16077                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16078                    break;
16079            }
16080        }
16081
16082        // Add to the sticky list if requested.
16083        if (sticky) {
16084            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16085                    callingPid, callingUid)
16086                    != PackageManager.PERMISSION_GRANTED) {
16087                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16088                        + callingPid + ", uid=" + callingUid
16089                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16090                Slog.w(TAG, msg);
16091                throw new SecurityException(msg);
16092            }
16093            if (requiredPermission != null) {
16094                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16095                        + " and enforce permission " + requiredPermission);
16096                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16097            }
16098            if (intent.getComponent() != null) {
16099                throw new SecurityException(
16100                        "Sticky broadcasts can't target a specific component");
16101            }
16102            // We use userId directly here, since the "all" target is maintained
16103            // as a separate set of sticky broadcasts.
16104            if (userId != UserHandle.USER_ALL) {
16105                // But first, if this is not a broadcast to all users, then
16106                // make sure it doesn't conflict with an existing broadcast to
16107                // all users.
16108                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16109                        UserHandle.USER_ALL);
16110                if (stickies != null) {
16111                    ArrayList<Intent> list = stickies.get(intent.getAction());
16112                    if (list != null) {
16113                        int N = list.size();
16114                        int i;
16115                        for (i=0; i<N; i++) {
16116                            if (intent.filterEquals(list.get(i))) {
16117                                throw new IllegalArgumentException(
16118                                        "Sticky broadcast " + intent + " for user "
16119                                        + userId + " conflicts with existing global broadcast");
16120                            }
16121                        }
16122                    }
16123                }
16124            }
16125            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16126            if (stickies == null) {
16127                stickies = new ArrayMap<String, ArrayList<Intent>>();
16128                mStickyBroadcasts.put(userId, stickies);
16129            }
16130            ArrayList<Intent> list = stickies.get(intent.getAction());
16131            if (list == null) {
16132                list = new ArrayList<Intent>();
16133                stickies.put(intent.getAction(), list);
16134            }
16135            int N = list.size();
16136            int i;
16137            for (i=0; i<N; i++) {
16138                if (intent.filterEquals(list.get(i))) {
16139                    // This sticky already exists, replace it.
16140                    list.set(i, new Intent(intent));
16141                    break;
16142                }
16143            }
16144            if (i >= N) {
16145                list.add(new Intent(intent));
16146            }
16147        }
16148
16149        int[] users;
16150        if (userId == UserHandle.USER_ALL) {
16151            // Caller wants broadcast to go to all started users.
16152            users = mStartedUserArray;
16153        } else {
16154            // Caller wants broadcast to go to one specific user.
16155            users = new int[] {userId};
16156        }
16157
16158        // Figure out who all will receive this broadcast.
16159        List receivers = null;
16160        List<BroadcastFilter> registeredReceivers = null;
16161        // Need to resolve the intent to interested receivers...
16162        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16163                 == 0) {
16164            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16165        }
16166        if (intent.getComponent() == null) {
16167            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16168                // Query one target user at a time, excluding shell-restricted users
16169                UserManagerService ums = getUserManagerLocked();
16170                for (int i = 0; i < users.length; i++) {
16171                    if (ums.hasUserRestriction(
16172                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16173                        continue;
16174                    }
16175                    List<BroadcastFilter> registeredReceiversForUser =
16176                            mReceiverResolver.queryIntent(intent,
16177                                    resolvedType, false, users[i]);
16178                    if (registeredReceivers == null) {
16179                        registeredReceivers = registeredReceiversForUser;
16180                    } else if (registeredReceiversForUser != null) {
16181                        registeredReceivers.addAll(registeredReceiversForUser);
16182                    }
16183                }
16184            } else {
16185                registeredReceivers = mReceiverResolver.queryIntent(intent,
16186                        resolvedType, false, userId);
16187            }
16188        }
16189
16190        final boolean replacePending =
16191                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16192
16193        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16194                + " replacePending=" + replacePending);
16195
16196        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16197        if (!ordered && NR > 0) {
16198            // If we are not serializing this broadcast, then send the
16199            // registered receivers separately so they don't wait for the
16200            // components to be launched.
16201            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16202            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16203                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16204                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16205                    ordered, sticky, false, userId);
16206            if (DEBUG_BROADCAST) Slog.v(
16207                    TAG, "Enqueueing parallel broadcast " + r);
16208            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16209            if (!replaced) {
16210                queue.enqueueParallelBroadcastLocked(r);
16211                queue.scheduleBroadcastsLocked();
16212            }
16213            registeredReceivers = null;
16214            NR = 0;
16215        }
16216
16217        // Merge into one list.
16218        int ir = 0;
16219        if (receivers != null) {
16220            // A special case for PACKAGE_ADDED: do not allow the package
16221            // being added to see this broadcast.  This prevents them from
16222            // using this as a back door to get run as soon as they are
16223            // installed.  Maybe in the future we want to have a special install
16224            // broadcast or such for apps, but we'd like to deliberately make
16225            // this decision.
16226            String skipPackages[] = null;
16227            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16228                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16229                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16230                Uri data = intent.getData();
16231                if (data != null) {
16232                    String pkgName = data.getSchemeSpecificPart();
16233                    if (pkgName != null) {
16234                        skipPackages = new String[] { pkgName };
16235                    }
16236                }
16237            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16238                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16239            }
16240            if (skipPackages != null && (skipPackages.length > 0)) {
16241                for (String skipPackage : skipPackages) {
16242                    if (skipPackage != null) {
16243                        int NT = receivers.size();
16244                        for (int it=0; it<NT; it++) {
16245                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16246                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16247                                receivers.remove(it);
16248                                it--;
16249                                NT--;
16250                            }
16251                        }
16252                    }
16253                }
16254            }
16255
16256            int NT = receivers != null ? receivers.size() : 0;
16257            int it = 0;
16258            ResolveInfo curt = null;
16259            BroadcastFilter curr = null;
16260            while (it < NT && ir < NR) {
16261                if (curt == null) {
16262                    curt = (ResolveInfo)receivers.get(it);
16263                }
16264                if (curr == null) {
16265                    curr = registeredReceivers.get(ir);
16266                }
16267                if (curr.getPriority() >= curt.priority) {
16268                    // Insert this broadcast record into the final list.
16269                    receivers.add(it, curr);
16270                    ir++;
16271                    curr = null;
16272                    it++;
16273                    NT++;
16274                } else {
16275                    // Skip to the next ResolveInfo in the final list.
16276                    it++;
16277                    curt = null;
16278                }
16279            }
16280        }
16281        while (ir < NR) {
16282            if (receivers == null) {
16283                receivers = new ArrayList();
16284            }
16285            receivers.add(registeredReceivers.get(ir));
16286            ir++;
16287        }
16288
16289        if ((receivers != null && receivers.size() > 0)
16290                || resultTo != null) {
16291            BroadcastQueue queue = broadcastQueueForIntent(intent);
16292            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16293                    callerPackage, callingPid, callingUid, resolvedType,
16294                    requiredPermission, appOp, receivers, resultTo, resultCode,
16295                    resultData, map, ordered, sticky, false, userId);
16296            if (DEBUG_BROADCAST) Slog.v(
16297                    TAG, "Enqueueing ordered broadcast " + r
16298                    + ": prev had " + queue.mOrderedBroadcasts.size());
16299            if (DEBUG_BROADCAST) {
16300                int seq = r.intent.getIntExtra("seq", -1);
16301                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16302            }
16303            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16304            if (!replaced) {
16305                queue.enqueueOrderedBroadcastLocked(r);
16306                queue.scheduleBroadcastsLocked();
16307            }
16308        }
16309
16310        return ActivityManager.BROADCAST_SUCCESS;
16311    }
16312
16313    final Intent verifyBroadcastLocked(Intent intent) {
16314        // Refuse possible leaked file descriptors
16315        if (intent != null && intent.hasFileDescriptors() == true) {
16316            throw new IllegalArgumentException("File descriptors passed in Intent");
16317        }
16318
16319        int flags = intent.getFlags();
16320
16321        if (!mProcessesReady) {
16322            // if the caller really truly claims to know what they're doing, go
16323            // ahead and allow the broadcast without launching any receivers
16324            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16325                intent = new Intent(intent);
16326                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16327            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16328                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16329                        + " before boot completion");
16330                throw new IllegalStateException("Cannot broadcast before boot completed");
16331            }
16332        }
16333
16334        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16335            throw new IllegalArgumentException(
16336                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16337        }
16338
16339        return intent;
16340    }
16341
16342    public final int broadcastIntent(IApplicationThread caller,
16343            Intent intent, String resolvedType, IIntentReceiver resultTo,
16344            int resultCode, String resultData, Bundle map,
16345            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16346        enforceNotIsolatedCaller("broadcastIntent");
16347        synchronized(this) {
16348            intent = verifyBroadcastLocked(intent);
16349
16350            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16351            final int callingPid = Binder.getCallingPid();
16352            final int callingUid = Binder.getCallingUid();
16353            final long origId = Binder.clearCallingIdentity();
16354            int res = broadcastIntentLocked(callerApp,
16355                    callerApp != null ? callerApp.info.packageName : null,
16356                    intent, resolvedType, resultTo,
16357                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16358                    callingPid, callingUid, userId);
16359            Binder.restoreCallingIdentity(origId);
16360            return res;
16361        }
16362    }
16363
16364    int broadcastIntentInPackage(String packageName, int uid,
16365            Intent intent, String resolvedType, IIntentReceiver resultTo,
16366            int resultCode, String resultData, Bundle map,
16367            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16368        synchronized(this) {
16369            intent = verifyBroadcastLocked(intent);
16370
16371            final long origId = Binder.clearCallingIdentity();
16372            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16373                    resultTo, resultCode, resultData, map, requiredPermission,
16374                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16375            Binder.restoreCallingIdentity(origId);
16376            return res;
16377        }
16378    }
16379
16380    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16381        // Refuse possible leaked file descriptors
16382        if (intent != null && intent.hasFileDescriptors() == true) {
16383            throw new IllegalArgumentException("File descriptors passed in Intent");
16384        }
16385
16386        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16387                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16388
16389        synchronized(this) {
16390            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16391                    != PackageManager.PERMISSION_GRANTED) {
16392                String msg = "Permission Denial: unbroadcastIntent() from pid="
16393                        + Binder.getCallingPid()
16394                        + ", uid=" + Binder.getCallingUid()
16395                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16396                Slog.w(TAG, msg);
16397                throw new SecurityException(msg);
16398            }
16399            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16400            if (stickies != null) {
16401                ArrayList<Intent> list = stickies.get(intent.getAction());
16402                if (list != null) {
16403                    int N = list.size();
16404                    int i;
16405                    for (i=0; i<N; i++) {
16406                        if (intent.filterEquals(list.get(i))) {
16407                            list.remove(i);
16408                            break;
16409                        }
16410                    }
16411                    if (list.size() <= 0) {
16412                        stickies.remove(intent.getAction());
16413                    }
16414                }
16415                if (stickies.size() <= 0) {
16416                    mStickyBroadcasts.remove(userId);
16417                }
16418            }
16419        }
16420    }
16421
16422    void backgroundServicesFinishedLocked(int userId) {
16423        for (BroadcastQueue queue : mBroadcastQueues) {
16424            queue.backgroundServicesFinishedLocked(userId);
16425        }
16426    }
16427
16428    public void finishReceiver(IBinder who, int resultCode, String resultData,
16429            Bundle resultExtras, boolean resultAbort, int flags) {
16430        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16431
16432        // Refuse possible leaked file descriptors
16433        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16434            throw new IllegalArgumentException("File descriptors passed in Bundle");
16435        }
16436
16437        final long origId = Binder.clearCallingIdentity();
16438        try {
16439            boolean doNext = false;
16440            BroadcastRecord r;
16441
16442            synchronized(this) {
16443                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16444                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16445                r = queue.getMatchingOrderedReceiver(who);
16446                if (r != null) {
16447                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16448                        resultData, resultExtras, resultAbort, true);
16449                }
16450            }
16451
16452            if (doNext) {
16453                r.queue.processNextBroadcast(false);
16454            }
16455            trimApplications();
16456        } finally {
16457            Binder.restoreCallingIdentity(origId);
16458        }
16459    }
16460
16461    // =========================================================
16462    // INSTRUMENTATION
16463    // =========================================================
16464
16465    public boolean startInstrumentation(ComponentName className,
16466            String profileFile, int flags, Bundle arguments,
16467            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16468            int userId, String abiOverride) {
16469        enforceNotIsolatedCaller("startInstrumentation");
16470        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16471                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16472        // Refuse possible leaked file descriptors
16473        if (arguments != null && arguments.hasFileDescriptors()) {
16474            throw new IllegalArgumentException("File descriptors passed in Bundle");
16475        }
16476
16477        synchronized(this) {
16478            InstrumentationInfo ii = null;
16479            ApplicationInfo ai = null;
16480            try {
16481                ii = mContext.getPackageManager().getInstrumentationInfo(
16482                    className, STOCK_PM_FLAGS);
16483                ai = AppGlobals.getPackageManager().getApplicationInfo(
16484                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16485            } catch (PackageManager.NameNotFoundException e) {
16486            } catch (RemoteException e) {
16487            }
16488            if (ii == null) {
16489                reportStartInstrumentationFailure(watcher, className,
16490                        "Unable to find instrumentation info for: " + className);
16491                return false;
16492            }
16493            if (ai == null) {
16494                reportStartInstrumentationFailure(watcher, className,
16495                        "Unable to find instrumentation target package: " + ii.targetPackage);
16496                return false;
16497            }
16498
16499            int match = mContext.getPackageManager().checkSignatures(
16500                    ii.targetPackage, ii.packageName);
16501            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16502                String msg = "Permission Denial: starting instrumentation "
16503                        + className + " from pid="
16504                        + Binder.getCallingPid()
16505                        + ", uid=" + Binder.getCallingPid()
16506                        + " not allowed because package " + ii.packageName
16507                        + " does not have a signature matching the target "
16508                        + ii.targetPackage;
16509                reportStartInstrumentationFailure(watcher, className, msg);
16510                throw new SecurityException(msg);
16511            }
16512
16513            final long origId = Binder.clearCallingIdentity();
16514            // Instrumentation can kill and relaunch even persistent processes
16515            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16516                    "start instr");
16517            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16518            app.instrumentationClass = className;
16519            app.instrumentationInfo = ai;
16520            app.instrumentationProfileFile = profileFile;
16521            app.instrumentationArguments = arguments;
16522            app.instrumentationWatcher = watcher;
16523            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16524            app.instrumentationResultClass = className;
16525            Binder.restoreCallingIdentity(origId);
16526        }
16527
16528        return true;
16529    }
16530
16531    /**
16532     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16533     * error to the logs, but if somebody is watching, send the report there too.  This enables
16534     * the "am" command to report errors with more information.
16535     *
16536     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16537     * @param cn The component name of the instrumentation.
16538     * @param report The error report.
16539     */
16540    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16541            ComponentName cn, String report) {
16542        Slog.w(TAG, report);
16543        try {
16544            if (watcher != null) {
16545                Bundle results = new Bundle();
16546                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16547                results.putString("Error", report);
16548                watcher.instrumentationStatus(cn, -1, results);
16549            }
16550        } catch (RemoteException e) {
16551            Slog.w(TAG, e);
16552        }
16553    }
16554
16555    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16556        if (app.instrumentationWatcher != null) {
16557            try {
16558                // NOTE:  IInstrumentationWatcher *must* be oneway here
16559                app.instrumentationWatcher.instrumentationFinished(
16560                    app.instrumentationClass,
16561                    resultCode,
16562                    results);
16563            } catch (RemoteException e) {
16564            }
16565        }
16566        if (app.instrumentationUiAutomationConnection != null) {
16567            try {
16568                app.instrumentationUiAutomationConnection.shutdown();
16569            } catch (RemoteException re) {
16570                /* ignore */
16571            }
16572            // Only a UiAutomation can set this flag and now that
16573            // it is finished we make sure it is reset to its default.
16574            mUserIsMonkey = false;
16575        }
16576        app.instrumentationWatcher = null;
16577        app.instrumentationUiAutomationConnection = null;
16578        app.instrumentationClass = null;
16579        app.instrumentationInfo = null;
16580        app.instrumentationProfileFile = null;
16581        app.instrumentationArguments = null;
16582
16583        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16584                "finished inst");
16585    }
16586
16587    public void finishInstrumentation(IApplicationThread target,
16588            int resultCode, Bundle results) {
16589        int userId = UserHandle.getCallingUserId();
16590        // Refuse possible leaked file descriptors
16591        if (results != null && results.hasFileDescriptors()) {
16592            throw new IllegalArgumentException("File descriptors passed in Intent");
16593        }
16594
16595        synchronized(this) {
16596            ProcessRecord app = getRecordForAppLocked(target);
16597            if (app == null) {
16598                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16599                return;
16600            }
16601            final long origId = Binder.clearCallingIdentity();
16602            finishInstrumentationLocked(app, resultCode, results);
16603            Binder.restoreCallingIdentity(origId);
16604        }
16605    }
16606
16607    // =========================================================
16608    // CONFIGURATION
16609    // =========================================================
16610
16611    public ConfigurationInfo getDeviceConfigurationInfo() {
16612        ConfigurationInfo config = new ConfigurationInfo();
16613        synchronized (this) {
16614            config.reqTouchScreen = mConfiguration.touchscreen;
16615            config.reqKeyboardType = mConfiguration.keyboard;
16616            config.reqNavigation = mConfiguration.navigation;
16617            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16618                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16619                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16620            }
16621            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16622                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16623                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16624            }
16625            config.reqGlEsVersion = GL_ES_VERSION;
16626        }
16627        return config;
16628    }
16629
16630    ActivityStack getFocusedStack() {
16631        return mStackSupervisor.getFocusedStack();
16632    }
16633
16634    public Configuration getConfiguration() {
16635        Configuration ci;
16636        synchronized(this) {
16637            ci = new Configuration(mConfiguration);
16638            ci.userSetLocale = false;
16639        }
16640        return ci;
16641    }
16642
16643    public void updatePersistentConfiguration(Configuration values) {
16644        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16645                "updateConfiguration()");
16646        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16647                "updateConfiguration()");
16648        if (values == null) {
16649            throw new NullPointerException("Configuration must not be null");
16650        }
16651
16652        synchronized(this) {
16653            final long origId = Binder.clearCallingIdentity();
16654            updateConfigurationLocked(values, null, true, false);
16655            Binder.restoreCallingIdentity(origId);
16656        }
16657    }
16658
16659    public void updateConfiguration(Configuration values) {
16660        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16661                "updateConfiguration()");
16662
16663        synchronized(this) {
16664            if (values == null && mWindowManager != null) {
16665                // sentinel: fetch the current configuration from the window manager
16666                values = mWindowManager.computeNewConfiguration();
16667            }
16668
16669            if (mWindowManager != null) {
16670                mProcessList.applyDisplaySize(mWindowManager);
16671            }
16672
16673            final long origId = Binder.clearCallingIdentity();
16674            if (values != null) {
16675                Settings.System.clearConfiguration(values);
16676            }
16677            updateConfigurationLocked(values, null, false, false);
16678            Binder.restoreCallingIdentity(origId);
16679        }
16680    }
16681
16682    /**
16683     * Do either or both things: (1) change the current configuration, and (2)
16684     * make sure the given activity is running with the (now) current
16685     * configuration.  Returns true if the activity has been left running, or
16686     * false if <var>starting</var> is being destroyed to match the new
16687     * configuration.
16688     * @param persistent TODO
16689     */
16690    boolean updateConfigurationLocked(Configuration values,
16691            ActivityRecord starting, boolean persistent, boolean initLocale) {
16692        int changes = 0;
16693
16694        if (values != null) {
16695            Configuration newConfig = new Configuration(mConfiguration);
16696            changes = newConfig.updateFrom(values);
16697            if (changes != 0) {
16698                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16699                    Slog.i(TAG, "Updating configuration to: " + values);
16700                }
16701
16702                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16703
16704                if (!initLocale && values.locale != null && values.userSetLocale) {
16705                    final String languageTag = values.locale.toLanguageTag();
16706                    SystemProperties.set("persist.sys.locale", languageTag);
16707                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16708                            values.locale));
16709                }
16710
16711                mConfigurationSeq++;
16712                if (mConfigurationSeq <= 0) {
16713                    mConfigurationSeq = 1;
16714                }
16715                newConfig.seq = mConfigurationSeq;
16716                mConfiguration = newConfig;
16717                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16718                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16719                //mUsageStatsService.noteStartConfig(newConfig);
16720
16721                final Configuration configCopy = new Configuration(mConfiguration);
16722
16723                // TODO: If our config changes, should we auto dismiss any currently
16724                // showing dialogs?
16725                mShowDialogs = shouldShowDialogs(newConfig);
16726
16727                AttributeCache ac = AttributeCache.instance();
16728                if (ac != null) {
16729                    ac.updateConfiguration(configCopy);
16730                }
16731
16732                // Make sure all resources in our process are updated
16733                // right now, so that anyone who is going to retrieve
16734                // resource values after we return will be sure to get
16735                // the new ones.  This is especially important during
16736                // boot, where the first config change needs to guarantee
16737                // all resources have that config before following boot
16738                // code is executed.
16739                mSystemThread.applyConfigurationToResources(configCopy);
16740
16741                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16742                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16743                    msg.obj = new Configuration(configCopy);
16744                    mHandler.sendMessage(msg);
16745                }
16746
16747                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16748                    ProcessRecord app = mLruProcesses.get(i);
16749                    try {
16750                        if (app.thread != null) {
16751                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16752                                    + app.processName + " new config " + mConfiguration);
16753                            app.thread.scheduleConfigurationChanged(configCopy);
16754                        }
16755                    } catch (Exception e) {
16756                    }
16757                }
16758                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16759                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16760                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16761                        | Intent.FLAG_RECEIVER_FOREGROUND);
16762                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16763                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16764                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16765                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16766                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16767                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16768                    broadcastIntentLocked(null, null, intent,
16769                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16770                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16771                }
16772            }
16773        }
16774
16775        boolean kept = true;
16776        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16777        // mainStack is null during startup.
16778        if (mainStack != null) {
16779            if (changes != 0 && starting == null) {
16780                // If the configuration changed, and the caller is not already
16781                // in the process of starting an activity, then find the top
16782                // activity to check if its configuration needs to change.
16783                starting = mainStack.topRunningActivityLocked(null);
16784            }
16785
16786            if (starting != null) {
16787                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16788                // And we need to make sure at this point that all other activities
16789                // are made visible with the correct configuration.
16790                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16791            }
16792        }
16793
16794        if (values != null && mWindowManager != null) {
16795            mWindowManager.setNewConfiguration(mConfiguration);
16796        }
16797
16798        return kept;
16799    }
16800
16801    /**
16802     * Decide based on the configuration whether we should shouw the ANR,
16803     * crash, etc dialogs.  The idea is that if there is no affordnace to
16804     * press the on-screen buttons, we shouldn't show the dialog.
16805     *
16806     * A thought: SystemUI might also want to get told about this, the Power
16807     * dialog / global actions also might want different behaviors.
16808     */
16809    private static final boolean shouldShowDialogs(Configuration config) {
16810        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16811                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16812    }
16813
16814    @Override
16815    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16816        synchronized (this) {
16817            ActivityRecord srec = ActivityRecord.forToken(token);
16818            if (srec.task != null && srec.task.stack != null) {
16819                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16820            }
16821        }
16822        return false;
16823    }
16824
16825    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16826            Intent resultData) {
16827
16828        synchronized (this) {
16829            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16830            if (stack != null) {
16831                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16832            }
16833            return false;
16834        }
16835    }
16836
16837    public int getLaunchedFromUid(IBinder activityToken) {
16838        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16839        if (srec == null) {
16840            return -1;
16841        }
16842        return srec.launchedFromUid;
16843    }
16844
16845    public String getLaunchedFromPackage(IBinder activityToken) {
16846        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16847        if (srec == null) {
16848            return null;
16849        }
16850        return srec.launchedFromPackage;
16851    }
16852
16853    // =========================================================
16854    // LIFETIME MANAGEMENT
16855    // =========================================================
16856
16857    // Returns which broadcast queue the app is the current [or imminent] receiver
16858    // on, or 'null' if the app is not an active broadcast recipient.
16859    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16860        BroadcastRecord r = app.curReceiver;
16861        if (r != null) {
16862            return r.queue;
16863        }
16864
16865        // It's not the current receiver, but it might be starting up to become one
16866        synchronized (this) {
16867            for (BroadcastQueue queue : mBroadcastQueues) {
16868                r = queue.mPendingBroadcast;
16869                if (r != null && r.curApp == app) {
16870                    // found it; report which queue it's in
16871                    return queue;
16872                }
16873            }
16874        }
16875
16876        return null;
16877    }
16878
16879    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16880            ComponentName targetComponent, String targetProcess) {
16881        if (!mTrackingAssociations) {
16882            return null;
16883        }
16884        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16885                = mAssociations.get(targetUid);
16886        if (components == null) {
16887            components = new ArrayMap<>();
16888            mAssociations.put(targetUid, components);
16889        }
16890        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16891        if (sourceUids == null) {
16892            sourceUids = new SparseArray<>();
16893            components.put(targetComponent, sourceUids);
16894        }
16895        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16896        if (sourceProcesses == null) {
16897            sourceProcesses = new ArrayMap<>();
16898            sourceUids.put(sourceUid, sourceProcesses);
16899        }
16900        Association ass = sourceProcesses.get(sourceProcess);
16901        if (ass == null) {
16902            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16903                    targetProcess);
16904            sourceProcesses.put(sourceProcess, ass);
16905        }
16906        ass.mCount++;
16907        ass.mNesting++;
16908        if (ass.mNesting == 1) {
16909            ass.mStartTime = SystemClock.uptimeMillis();
16910        }
16911        return ass;
16912    }
16913
16914    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16915            ComponentName targetComponent) {
16916        if (!mTrackingAssociations) {
16917            return;
16918        }
16919        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16920                = mAssociations.get(targetUid);
16921        if (components == null) {
16922            return;
16923        }
16924        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16925        if (sourceUids == null) {
16926            return;
16927        }
16928        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16929        if (sourceProcesses == null) {
16930            return;
16931        }
16932        Association ass = sourceProcesses.get(sourceProcess);
16933        if (ass == null || ass.mNesting <= 0) {
16934            return;
16935        }
16936        ass.mNesting--;
16937        if (ass.mNesting == 0) {
16938            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16939        }
16940    }
16941
16942    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16943            boolean doingAll, long now) {
16944        if (mAdjSeq == app.adjSeq) {
16945            // This adjustment has already been computed.
16946            return app.curRawAdj;
16947        }
16948
16949        if (app.thread == null) {
16950            app.adjSeq = mAdjSeq;
16951            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16952            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16953            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16954        }
16955
16956        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16957        app.adjSource = null;
16958        app.adjTarget = null;
16959        app.empty = false;
16960        app.cached = false;
16961
16962        final int activitiesSize = app.activities.size();
16963
16964        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16965            // The max adjustment doesn't allow this app to be anything
16966            // below foreground, so it is not worth doing work for it.
16967            app.adjType = "fixed";
16968            app.adjSeq = mAdjSeq;
16969            app.curRawAdj = app.maxAdj;
16970            app.foregroundActivities = false;
16971            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16972            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16973            // System processes can do UI, and when they do we want to have
16974            // them trim their memory after the user leaves the UI.  To
16975            // facilitate this, here we need to determine whether or not it
16976            // is currently showing UI.
16977            app.systemNoUi = true;
16978            if (app == TOP_APP) {
16979                app.systemNoUi = false;
16980            } else if (activitiesSize > 0) {
16981                for (int j = 0; j < activitiesSize; j++) {
16982                    final ActivityRecord r = app.activities.get(j);
16983                    if (r.visible) {
16984                        app.systemNoUi = false;
16985                    }
16986                }
16987            }
16988            if (!app.systemNoUi) {
16989                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16990            }
16991            return (app.curAdj=app.maxAdj);
16992        }
16993
16994        app.systemNoUi = false;
16995
16996        // Determine the importance of the process, starting with most
16997        // important to least, and assign an appropriate OOM adjustment.
16998        int adj;
16999        int schedGroup;
17000        int procState;
17001        boolean foregroundActivities = false;
17002        BroadcastQueue queue;
17003        if (app == TOP_APP) {
17004            // The last app on the list is the foreground app.
17005            adj = ProcessList.FOREGROUND_APP_ADJ;
17006            schedGroup = Process.THREAD_GROUP_DEFAULT;
17007            app.adjType = "top-activity";
17008            foregroundActivities = true;
17009            procState = ActivityManager.PROCESS_STATE_TOP;
17010        } else if (app.instrumentationClass != null) {
17011            // Don't want to kill running instrumentation.
17012            adj = ProcessList.FOREGROUND_APP_ADJ;
17013            schedGroup = Process.THREAD_GROUP_DEFAULT;
17014            app.adjType = "instrumentation";
17015            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17016        } else if ((queue = isReceivingBroadcast(app)) != null) {
17017            // An app that is currently receiving a broadcast also
17018            // counts as being in the foreground for OOM killer purposes.
17019            // It's placed in a sched group based on the nature of the
17020            // broadcast as reflected by which queue it's active in.
17021            adj = ProcessList.FOREGROUND_APP_ADJ;
17022            schedGroup = (queue == mFgBroadcastQueue)
17023                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17024            app.adjType = "broadcast";
17025            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17026        } else if (app.executingServices.size() > 0) {
17027            // An app that is currently executing a service callback also
17028            // counts as being in the foreground.
17029            adj = ProcessList.FOREGROUND_APP_ADJ;
17030            schedGroup = app.execServicesFg ?
17031                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17032            app.adjType = "exec-service";
17033            procState = ActivityManager.PROCESS_STATE_SERVICE;
17034            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17035        } else {
17036            // As far as we know the process is empty.  We may change our mind later.
17037            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17038            // At this point we don't actually know the adjustment.  Use the cached adj
17039            // value that the caller wants us to.
17040            adj = cachedAdj;
17041            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17042            app.cached = true;
17043            app.empty = true;
17044            app.adjType = "cch-empty";
17045        }
17046
17047        // Examine all activities if not already foreground.
17048        if (!foregroundActivities && activitiesSize > 0) {
17049            for (int j = 0; j < activitiesSize; j++) {
17050                final ActivityRecord r = app.activities.get(j);
17051                if (r.app != app) {
17052                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17053                            + app + "?!?");
17054                    continue;
17055                }
17056                if (r.visible) {
17057                    // App has a visible activity; only upgrade adjustment.
17058                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17059                        adj = ProcessList.VISIBLE_APP_ADJ;
17060                        app.adjType = "visible";
17061                    }
17062                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17063                        procState = ActivityManager.PROCESS_STATE_TOP;
17064                    }
17065                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17066                    app.cached = false;
17067                    app.empty = false;
17068                    foregroundActivities = true;
17069                    break;
17070                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17071                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17072                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17073                        app.adjType = "pausing";
17074                    }
17075                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17076                        procState = ActivityManager.PROCESS_STATE_TOP;
17077                    }
17078                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17079                    app.cached = false;
17080                    app.empty = false;
17081                    foregroundActivities = true;
17082                } else if (r.state == ActivityState.STOPPING) {
17083                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17084                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17085                        app.adjType = "stopping";
17086                    }
17087                    // For the process state, we will at this point consider the
17088                    // process to be cached.  It will be cached either as an activity
17089                    // or empty depending on whether the activity is finishing.  We do
17090                    // this so that we can treat the process as cached for purposes of
17091                    // memory trimming (determing current memory level, trim command to
17092                    // send to process) since there can be an arbitrary number of stopping
17093                    // processes and they should soon all go into the cached state.
17094                    if (!r.finishing) {
17095                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17096                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17097                        }
17098                    }
17099                    app.cached = false;
17100                    app.empty = false;
17101                    foregroundActivities = true;
17102                } else {
17103                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17104                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17105                        app.adjType = "cch-act";
17106                    }
17107                }
17108            }
17109        }
17110
17111        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17112            if (app.foregroundServices) {
17113                // The user is aware of this app, so make it visible.
17114                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17115                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17116                app.cached = false;
17117                app.adjType = "fg-service";
17118                schedGroup = Process.THREAD_GROUP_DEFAULT;
17119            } else if (app.forcingToForeground != null) {
17120                // The user is aware of this app, so make it visible.
17121                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17122                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17123                app.cached = false;
17124                app.adjType = "force-fg";
17125                app.adjSource = app.forcingToForeground;
17126                schedGroup = Process.THREAD_GROUP_DEFAULT;
17127            }
17128        }
17129
17130        if (app == mHeavyWeightProcess) {
17131            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17132                // We don't want to kill the current heavy-weight process.
17133                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17134                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17135                app.cached = false;
17136                app.adjType = "heavy";
17137            }
17138            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17139                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17140            }
17141        }
17142
17143        if (app == mHomeProcess) {
17144            if (adj > ProcessList.HOME_APP_ADJ) {
17145                // This process is hosting what we currently consider to be the
17146                // home app, so we don't want to let it go into the background.
17147                adj = ProcessList.HOME_APP_ADJ;
17148                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17149                app.cached = false;
17150                app.adjType = "home";
17151            }
17152            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17153                procState = ActivityManager.PROCESS_STATE_HOME;
17154            }
17155        }
17156
17157        if (app == mPreviousProcess && app.activities.size() > 0) {
17158            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17159                // This was the previous process that showed UI to the user.
17160                // We want to try to keep it around more aggressively, to give
17161                // a good experience around switching between two apps.
17162                adj = ProcessList.PREVIOUS_APP_ADJ;
17163                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17164                app.cached = false;
17165                app.adjType = "previous";
17166            }
17167            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17168                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17169            }
17170        }
17171
17172        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17173                + " reason=" + app.adjType);
17174
17175        // By default, we use the computed adjustment.  It may be changed if
17176        // there are applications dependent on our services or providers, but
17177        // this gives us a baseline and makes sure we don't get into an
17178        // infinite recursion.
17179        app.adjSeq = mAdjSeq;
17180        app.curRawAdj = adj;
17181        app.hasStartedServices = false;
17182
17183        if (mBackupTarget != null && app == mBackupTarget.app) {
17184            // If possible we want to avoid killing apps while they're being backed up
17185            if (adj > ProcessList.BACKUP_APP_ADJ) {
17186                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17187                adj = ProcessList.BACKUP_APP_ADJ;
17188                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17189                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17190                }
17191                app.adjType = "backup";
17192                app.cached = false;
17193            }
17194            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17195                procState = ActivityManager.PROCESS_STATE_BACKUP;
17196            }
17197        }
17198
17199        boolean mayBeTop = false;
17200
17201        for (int is = app.services.size()-1;
17202                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17203                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17204                        || procState > ActivityManager.PROCESS_STATE_TOP);
17205                is--) {
17206            ServiceRecord s = app.services.valueAt(is);
17207            if (s.startRequested) {
17208                app.hasStartedServices = true;
17209                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17210                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17211                }
17212                if (app.hasShownUi && app != mHomeProcess) {
17213                    // If this process has shown some UI, let it immediately
17214                    // go to the LRU list because it may be pretty heavy with
17215                    // UI stuff.  We'll tag it with a label just to help
17216                    // debug and understand what is going on.
17217                    if (adj > ProcessList.SERVICE_ADJ) {
17218                        app.adjType = "cch-started-ui-services";
17219                    }
17220                } else {
17221                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17222                        // This service has seen some activity within
17223                        // recent memory, so we will keep its process ahead
17224                        // of the background processes.
17225                        if (adj > ProcessList.SERVICE_ADJ) {
17226                            adj = ProcessList.SERVICE_ADJ;
17227                            app.adjType = "started-services";
17228                            app.cached = false;
17229                        }
17230                    }
17231                    // If we have let the service slide into the background
17232                    // state, still have some text describing what it is doing
17233                    // even though the service no longer has an impact.
17234                    if (adj > ProcessList.SERVICE_ADJ) {
17235                        app.adjType = "cch-started-services";
17236                    }
17237                }
17238            }
17239            for (int conni = s.connections.size()-1;
17240                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17241                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17242                            || procState > ActivityManager.PROCESS_STATE_TOP);
17243                    conni--) {
17244                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17245                for (int i = 0;
17246                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17247                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17248                                || procState > ActivityManager.PROCESS_STATE_TOP);
17249                        i++) {
17250                    // XXX should compute this based on the max of
17251                    // all connected clients.
17252                    ConnectionRecord cr = clist.get(i);
17253                    if (cr.binding.client == app) {
17254                        // Binding to ourself is not interesting.
17255                        continue;
17256                    }
17257                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17258                        ProcessRecord client = cr.binding.client;
17259                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17260                                TOP_APP, doingAll, now);
17261                        int clientProcState = client.curProcState;
17262                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17263                            // If the other app is cached for any reason, for purposes here
17264                            // we are going to consider it empty.  The specific cached state
17265                            // doesn't propagate except under certain conditions.
17266                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17267                        }
17268                        String adjType = null;
17269                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17270                            // Not doing bind OOM management, so treat
17271                            // this guy more like a started service.
17272                            if (app.hasShownUi && app != mHomeProcess) {
17273                                // If this process has shown some UI, let it immediately
17274                                // go to the LRU list because it may be pretty heavy with
17275                                // UI stuff.  We'll tag it with a label just to help
17276                                // debug and understand what is going on.
17277                                if (adj > clientAdj) {
17278                                    adjType = "cch-bound-ui-services";
17279                                }
17280                                app.cached = false;
17281                                clientAdj = adj;
17282                                clientProcState = procState;
17283                            } else {
17284                                if (now >= (s.lastActivity
17285                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17286                                    // This service has not seen activity within
17287                                    // recent memory, so allow it to drop to the
17288                                    // LRU list if there is no other reason to keep
17289                                    // it around.  We'll also tag it with a label just
17290                                    // to help debug and undertand what is going on.
17291                                    if (adj > clientAdj) {
17292                                        adjType = "cch-bound-services";
17293                                    }
17294                                    clientAdj = adj;
17295                                }
17296                            }
17297                        }
17298                        if (adj > clientAdj) {
17299                            // If this process has recently shown UI, and
17300                            // the process that is binding to it is less
17301                            // important than being visible, then we don't
17302                            // care about the binding as much as we care
17303                            // about letting this process get into the LRU
17304                            // list to be killed and restarted if needed for
17305                            // memory.
17306                            if (app.hasShownUi && app != mHomeProcess
17307                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17308                                adjType = "cch-bound-ui-services";
17309                            } else {
17310                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17311                                        |Context.BIND_IMPORTANT)) != 0) {
17312                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17313                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17314                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17315                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17316                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17317                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17318                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17319                                    adj = clientAdj;
17320                                } else {
17321                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17322                                        adj = ProcessList.VISIBLE_APP_ADJ;
17323                                    }
17324                                }
17325                                if (!client.cached) {
17326                                    app.cached = false;
17327                                }
17328                                adjType = "service";
17329                            }
17330                        }
17331                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17332                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17333                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17334                            }
17335                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17336                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17337                                    // Special handling of clients who are in the top state.
17338                                    // We *may* want to consider this process to be in the
17339                                    // top state as well, but only if there is not another
17340                                    // reason for it to be running.  Being on the top is a
17341                                    // special state, meaning you are specifically running
17342                                    // for the current top app.  If the process is already
17343                                    // running in the background for some other reason, it
17344                                    // is more important to continue considering it to be
17345                                    // in the background state.
17346                                    mayBeTop = true;
17347                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17348                                } else {
17349                                    // Special handling for above-top states (persistent
17350                                    // processes).  These should not bring the current process
17351                                    // into the top state, since they are not on top.  Instead
17352                                    // give them the best state after that.
17353                                    clientProcState =
17354                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17355                                }
17356                            }
17357                        } else {
17358                            if (clientProcState <
17359                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17360                                clientProcState =
17361                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17362                            }
17363                        }
17364                        if (procState > clientProcState) {
17365                            procState = clientProcState;
17366                        }
17367                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17368                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17369                            app.pendingUiClean = true;
17370                        }
17371                        if (adjType != null) {
17372                            app.adjType = adjType;
17373                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17374                                    .REASON_SERVICE_IN_USE;
17375                            app.adjSource = cr.binding.client;
17376                            app.adjSourceProcState = clientProcState;
17377                            app.adjTarget = s.name;
17378                        }
17379                    }
17380                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17381                        app.treatLikeActivity = true;
17382                    }
17383                    final ActivityRecord a = cr.activity;
17384                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17385                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17386                                (a.visible || a.state == ActivityState.RESUMED
17387                                 || a.state == ActivityState.PAUSING)) {
17388                            adj = ProcessList.FOREGROUND_APP_ADJ;
17389                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17390                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17391                            }
17392                            app.cached = false;
17393                            app.adjType = "service";
17394                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17395                                    .REASON_SERVICE_IN_USE;
17396                            app.adjSource = a;
17397                            app.adjSourceProcState = procState;
17398                            app.adjTarget = s.name;
17399                        }
17400                    }
17401                }
17402            }
17403        }
17404
17405        for (int provi = app.pubProviders.size()-1;
17406                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17407                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17408                        || procState > ActivityManager.PROCESS_STATE_TOP);
17409                provi--) {
17410            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17411            for (int i = cpr.connections.size()-1;
17412                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17413                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17414                            || procState > ActivityManager.PROCESS_STATE_TOP);
17415                    i--) {
17416                ContentProviderConnection conn = cpr.connections.get(i);
17417                ProcessRecord client = conn.client;
17418                if (client == app) {
17419                    // Being our own client is not interesting.
17420                    continue;
17421                }
17422                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17423                int clientProcState = client.curProcState;
17424                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17425                    // If the other app is cached for any reason, for purposes here
17426                    // we are going to consider it empty.
17427                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17428                }
17429                if (adj > clientAdj) {
17430                    if (app.hasShownUi && app != mHomeProcess
17431                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17432                        app.adjType = "cch-ui-provider";
17433                    } else {
17434                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17435                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17436                        app.adjType = "provider";
17437                    }
17438                    app.cached &= client.cached;
17439                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17440                            .REASON_PROVIDER_IN_USE;
17441                    app.adjSource = client;
17442                    app.adjSourceProcState = clientProcState;
17443                    app.adjTarget = cpr.name;
17444                }
17445                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17446                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17447                        // Special handling of clients who are in the top state.
17448                        // We *may* want to consider this process to be in the
17449                        // top state as well, but only if there is not another
17450                        // reason for it to be running.  Being on the top is a
17451                        // special state, meaning you are specifically running
17452                        // for the current top app.  If the process is already
17453                        // running in the background for some other reason, it
17454                        // is more important to continue considering it to be
17455                        // in the background state.
17456                        mayBeTop = true;
17457                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17458                    } else {
17459                        // Special handling for above-top states (persistent
17460                        // processes).  These should not bring the current process
17461                        // into the top state, since they are not on top.  Instead
17462                        // give them the best state after that.
17463                        clientProcState =
17464                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17465                    }
17466                }
17467                if (procState > clientProcState) {
17468                    procState = clientProcState;
17469                }
17470                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17471                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17472                }
17473            }
17474            // If the provider has external (non-framework) process
17475            // dependencies, ensure that its adjustment is at least
17476            // FOREGROUND_APP_ADJ.
17477            if (cpr.hasExternalProcessHandles()) {
17478                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17479                    adj = ProcessList.FOREGROUND_APP_ADJ;
17480                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17481                    app.cached = false;
17482                    app.adjType = "provider";
17483                    app.adjTarget = cpr.name;
17484                }
17485                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17486                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17487                }
17488            }
17489        }
17490
17491        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17492            // A client of one of our services or providers is in the top state.  We
17493            // *may* want to be in the top state, but not if we are already running in
17494            // the background for some other reason.  For the decision here, we are going
17495            // to pick out a few specific states that we want to remain in when a client
17496            // is top (states that tend to be longer-term) and otherwise allow it to go
17497            // to the top state.
17498            switch (procState) {
17499                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17500                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17501                case ActivityManager.PROCESS_STATE_SERVICE:
17502                    // These all are longer-term states, so pull them up to the top
17503                    // of the background states, but not all the way to the top state.
17504                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17505                    break;
17506                default:
17507                    // Otherwise, top is a better choice, so take it.
17508                    procState = ActivityManager.PROCESS_STATE_TOP;
17509                    break;
17510            }
17511        }
17512
17513        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17514            if (app.hasClientActivities) {
17515                // This is a cached process, but with client activities.  Mark it so.
17516                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17517                app.adjType = "cch-client-act";
17518            } else if (app.treatLikeActivity) {
17519                // This is a cached process, but somebody wants us to treat it like it has
17520                // an activity, okay!
17521                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17522                app.adjType = "cch-as-act";
17523            }
17524        }
17525
17526        if (adj == ProcessList.SERVICE_ADJ) {
17527            if (doingAll) {
17528                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17529                mNewNumServiceProcs++;
17530                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17531                if (!app.serviceb) {
17532                    // This service isn't far enough down on the LRU list to
17533                    // normally be a B service, but if we are low on RAM and it
17534                    // is large we want to force it down since we would prefer to
17535                    // keep launcher over it.
17536                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17537                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17538                        app.serviceHighRam = true;
17539                        app.serviceb = true;
17540                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17541                    } else {
17542                        mNewNumAServiceProcs++;
17543                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17544                    }
17545                } else {
17546                    app.serviceHighRam = false;
17547                }
17548            }
17549            if (app.serviceb) {
17550                adj = ProcessList.SERVICE_B_ADJ;
17551            }
17552        }
17553
17554        app.curRawAdj = adj;
17555
17556        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17557        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17558        if (adj > app.maxAdj) {
17559            adj = app.maxAdj;
17560            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17561                schedGroup = Process.THREAD_GROUP_DEFAULT;
17562            }
17563        }
17564
17565        // Do final modification to adj.  Everything we do between here and applying
17566        // the final setAdj must be done in this function, because we will also use
17567        // it when computing the final cached adj later.  Note that we don't need to
17568        // worry about this for max adj above, since max adj will always be used to
17569        // keep it out of the cached vaues.
17570        app.curAdj = app.modifyRawOomAdj(adj);
17571        app.curSchedGroup = schedGroup;
17572        app.curProcState = procState;
17573        app.foregroundActivities = foregroundActivities;
17574
17575        return app.curRawAdj;
17576    }
17577
17578    /**
17579     * Record new PSS sample for a process.
17580     */
17581    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17582        proc.lastPssTime = now;
17583        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17584        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17585                + ": " + pss + " lastPss=" + proc.lastPss
17586                + " state=" + ProcessList.makeProcStateString(procState));
17587        if (proc.initialIdlePss == 0) {
17588            proc.initialIdlePss = pss;
17589        }
17590        proc.lastPss = pss;
17591        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17592            proc.lastCachedPss = pss;
17593        }
17594    }
17595
17596    /**
17597     * Schedule PSS collection of a process.
17598     */
17599    void requestPssLocked(ProcessRecord proc, int procState) {
17600        if (mPendingPssProcesses.contains(proc)) {
17601            return;
17602        }
17603        if (mPendingPssProcesses.size() == 0) {
17604            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17605        }
17606        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17607        proc.pssProcState = procState;
17608        mPendingPssProcesses.add(proc);
17609    }
17610
17611    /**
17612     * Schedule PSS collection of all processes.
17613     */
17614    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17615        if (!always) {
17616            if (now < (mLastFullPssTime +
17617                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17618                return;
17619            }
17620        }
17621        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17622        mLastFullPssTime = now;
17623        mFullPssPending = true;
17624        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17625        mPendingPssProcesses.clear();
17626        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17627            ProcessRecord app = mLruProcesses.get(i);
17628            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17629                app.pssProcState = app.setProcState;
17630                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17631                        mTestPssMode, isSleeping(), now);
17632                mPendingPssProcesses.add(app);
17633            }
17634        }
17635        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17636    }
17637
17638    public void setTestPssMode(boolean enabled) {
17639        synchronized (this) {
17640            mTestPssMode = enabled;
17641            if (enabled) {
17642                // Whenever we enable the mode, we want to take a snapshot all of current
17643                // process mem use.
17644                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17645            }
17646        }
17647    }
17648
17649    /**
17650     * Ask a given process to GC right now.
17651     */
17652    final void performAppGcLocked(ProcessRecord app) {
17653        try {
17654            app.lastRequestedGc = SystemClock.uptimeMillis();
17655            if (app.thread != null) {
17656                if (app.reportLowMemory) {
17657                    app.reportLowMemory = false;
17658                    app.thread.scheduleLowMemory();
17659                } else {
17660                    app.thread.processInBackground();
17661                }
17662            }
17663        } catch (Exception e) {
17664            // whatever.
17665        }
17666    }
17667
17668    /**
17669     * Returns true if things are idle enough to perform GCs.
17670     */
17671    private final boolean canGcNowLocked() {
17672        boolean processingBroadcasts = false;
17673        for (BroadcastQueue q : mBroadcastQueues) {
17674            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17675                processingBroadcasts = true;
17676            }
17677        }
17678        return !processingBroadcasts
17679                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17680    }
17681
17682    /**
17683     * Perform GCs on all processes that are waiting for it, but only
17684     * if things are idle.
17685     */
17686    final void performAppGcsLocked() {
17687        final int N = mProcessesToGc.size();
17688        if (N <= 0) {
17689            return;
17690        }
17691        if (canGcNowLocked()) {
17692            while (mProcessesToGc.size() > 0) {
17693                ProcessRecord proc = mProcessesToGc.remove(0);
17694                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17695                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17696                            <= SystemClock.uptimeMillis()) {
17697                        // To avoid spamming the system, we will GC processes one
17698                        // at a time, waiting a few seconds between each.
17699                        performAppGcLocked(proc);
17700                        scheduleAppGcsLocked();
17701                        return;
17702                    } else {
17703                        // It hasn't been long enough since we last GCed this
17704                        // process...  put it in the list to wait for its time.
17705                        addProcessToGcListLocked(proc);
17706                        break;
17707                    }
17708                }
17709            }
17710
17711            scheduleAppGcsLocked();
17712        }
17713    }
17714
17715    /**
17716     * If all looks good, perform GCs on all processes waiting for them.
17717     */
17718    final void performAppGcsIfAppropriateLocked() {
17719        if (canGcNowLocked()) {
17720            performAppGcsLocked();
17721            return;
17722        }
17723        // Still not idle, wait some more.
17724        scheduleAppGcsLocked();
17725    }
17726
17727    /**
17728     * Schedule the execution of all pending app GCs.
17729     */
17730    final void scheduleAppGcsLocked() {
17731        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17732
17733        if (mProcessesToGc.size() > 0) {
17734            // Schedule a GC for the time to the next process.
17735            ProcessRecord proc = mProcessesToGc.get(0);
17736            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17737
17738            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17739            long now = SystemClock.uptimeMillis();
17740            if (when < (now+GC_TIMEOUT)) {
17741                when = now + GC_TIMEOUT;
17742            }
17743            mHandler.sendMessageAtTime(msg, when);
17744        }
17745    }
17746
17747    /**
17748     * Add a process to the array of processes waiting to be GCed.  Keeps the
17749     * list in sorted order by the last GC time.  The process can't already be
17750     * on the list.
17751     */
17752    final void addProcessToGcListLocked(ProcessRecord proc) {
17753        boolean added = false;
17754        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17755            if (mProcessesToGc.get(i).lastRequestedGc <
17756                    proc.lastRequestedGc) {
17757                added = true;
17758                mProcessesToGc.add(i+1, proc);
17759                break;
17760            }
17761        }
17762        if (!added) {
17763            mProcessesToGc.add(0, proc);
17764        }
17765    }
17766
17767    /**
17768     * Set up to ask a process to GC itself.  This will either do it
17769     * immediately, or put it on the list of processes to gc the next
17770     * time things are idle.
17771     */
17772    final void scheduleAppGcLocked(ProcessRecord app) {
17773        long now = SystemClock.uptimeMillis();
17774        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17775            return;
17776        }
17777        if (!mProcessesToGc.contains(app)) {
17778            addProcessToGcListLocked(app);
17779            scheduleAppGcsLocked();
17780        }
17781    }
17782
17783    final void checkExcessivePowerUsageLocked(boolean doKills) {
17784        updateCpuStatsNow();
17785
17786        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17787        boolean doWakeKills = doKills;
17788        boolean doCpuKills = doKills;
17789        if (mLastPowerCheckRealtime == 0) {
17790            doWakeKills = false;
17791        }
17792        if (mLastPowerCheckUptime == 0) {
17793            doCpuKills = false;
17794        }
17795        if (stats.isScreenOn()) {
17796            doWakeKills = false;
17797        }
17798        final long curRealtime = SystemClock.elapsedRealtime();
17799        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17800        final long curUptime = SystemClock.uptimeMillis();
17801        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17802        mLastPowerCheckRealtime = curRealtime;
17803        mLastPowerCheckUptime = curUptime;
17804        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17805            doWakeKills = false;
17806        }
17807        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17808            doCpuKills = false;
17809        }
17810        int i = mLruProcesses.size();
17811        while (i > 0) {
17812            i--;
17813            ProcessRecord app = mLruProcesses.get(i);
17814            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17815                long wtime;
17816                synchronized (stats) {
17817                    wtime = stats.getProcessWakeTime(app.info.uid,
17818                            app.pid, curRealtime);
17819                }
17820                long wtimeUsed = wtime - app.lastWakeTime;
17821                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17822                if (DEBUG_POWER) {
17823                    StringBuilder sb = new StringBuilder(128);
17824                    sb.append("Wake for ");
17825                    app.toShortString(sb);
17826                    sb.append(": over ");
17827                    TimeUtils.formatDuration(realtimeSince, sb);
17828                    sb.append(" used ");
17829                    TimeUtils.formatDuration(wtimeUsed, sb);
17830                    sb.append(" (");
17831                    sb.append((wtimeUsed*100)/realtimeSince);
17832                    sb.append("%)");
17833                    Slog.i(TAG, sb.toString());
17834                    sb.setLength(0);
17835                    sb.append("CPU for ");
17836                    app.toShortString(sb);
17837                    sb.append(": over ");
17838                    TimeUtils.formatDuration(uptimeSince, sb);
17839                    sb.append(" used ");
17840                    TimeUtils.formatDuration(cputimeUsed, sb);
17841                    sb.append(" (");
17842                    sb.append((cputimeUsed*100)/uptimeSince);
17843                    sb.append("%)");
17844                    Slog.i(TAG, sb.toString());
17845                }
17846                // If a process has held a wake lock for more
17847                // than 50% of the time during this period,
17848                // that sounds bad.  Kill!
17849                if (doWakeKills && realtimeSince > 0
17850                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17851                    synchronized (stats) {
17852                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17853                                realtimeSince, wtimeUsed);
17854                    }
17855                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17856                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17857                } else if (doCpuKills && uptimeSince > 0
17858                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17859                    synchronized (stats) {
17860                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17861                                uptimeSince, cputimeUsed);
17862                    }
17863                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17864                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17865                } else {
17866                    app.lastWakeTime = wtime;
17867                    app.lastCpuTime = app.curCpuTime;
17868                }
17869            }
17870        }
17871    }
17872
17873    private final boolean applyOomAdjLocked(ProcessRecord app,
17874            ProcessRecord TOP_APP, boolean doingAll, long now) {
17875        boolean success = true;
17876
17877        if (app.curRawAdj != app.setRawAdj) {
17878            app.setRawAdj = app.curRawAdj;
17879        }
17880
17881        int changes = 0;
17882
17883        if (app.curAdj != app.setAdj) {
17884            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17885            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17886                TAG, "Set " + app.pid + " " + app.processName +
17887                " adj " + app.curAdj + ": " + app.adjType);
17888            app.setAdj = app.curAdj;
17889        }
17890
17891        if (app.setSchedGroup != app.curSchedGroup) {
17892            app.setSchedGroup = app.curSchedGroup;
17893            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17894                    "Setting process group of " + app.processName
17895                    + " to " + app.curSchedGroup);
17896            if (app.waitingToKill != null &&
17897                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17898                app.kill(app.waitingToKill, true);
17899                success = false;
17900            } else {
17901                if (true) {
17902                    long oldId = Binder.clearCallingIdentity();
17903                    try {
17904                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17905                    } catch (Exception e) {
17906                        Slog.w(TAG, "Failed setting process group of " + app.pid
17907                                + " to " + app.curSchedGroup);
17908                        e.printStackTrace();
17909                    } finally {
17910                        Binder.restoreCallingIdentity(oldId);
17911                    }
17912                } else {
17913                    if (app.thread != null) {
17914                        try {
17915                            app.thread.setSchedulingGroup(app.curSchedGroup);
17916                        } catch (RemoteException e) {
17917                        }
17918                    }
17919                }
17920                Process.setSwappiness(app.pid,
17921                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17922            }
17923        }
17924        if (app.repForegroundActivities != app.foregroundActivities) {
17925            app.repForegroundActivities = app.foregroundActivities;
17926            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17927        }
17928        if (app.repProcState != app.curProcState) {
17929            app.repProcState = app.curProcState;
17930            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17931            if (app.thread != null) {
17932                try {
17933                    if (false) {
17934                        //RuntimeException h = new RuntimeException("here");
17935                        Slog.i(TAG, "Sending new process state " + app.repProcState
17936                                + " to " + app /*, h*/);
17937                    }
17938                    app.thread.setProcessState(app.repProcState);
17939                } catch (RemoteException e) {
17940                }
17941            }
17942        }
17943        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17944                app.setProcState)) {
17945            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17946                // Experimental code to more aggressively collect pss while
17947                // running test...  the problem is that this tends to collect
17948                // the data right when a process is transitioning between process
17949                // states, which well tend to give noisy data.
17950                long start = SystemClock.uptimeMillis();
17951                long pss = Debug.getPss(app.pid, mTmpLong, null);
17952                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17953                mPendingPssProcesses.remove(app);
17954                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17955                        + " to " + app.curProcState + ": "
17956                        + (SystemClock.uptimeMillis()-start) + "ms");
17957            }
17958            app.lastStateTime = now;
17959            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17960                    mTestPssMode, isSleeping(), now);
17961            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17962                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17963                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17964                    + (app.nextPssTime-now) + ": " + app);
17965        } else {
17966            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17967                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17968                    mTestPssMode)))) {
17969                requestPssLocked(app, app.setProcState);
17970                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17971                        mTestPssMode, isSleeping(), now);
17972            } else if (false && DEBUG_PSS) {
17973                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17974            }
17975        }
17976        if (app.setProcState != app.curProcState) {
17977            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17978                    "Proc state change of " + app.processName
17979                    + " to " + app.curProcState);
17980            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17981            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17982            if (setImportant && !curImportant) {
17983                // This app is no longer something we consider important enough to allow to
17984                // use arbitrary amounts of battery power.  Note
17985                // its current wake lock time to later know to kill it if
17986                // it is not behaving well.
17987                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17988                synchronized (stats) {
17989                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17990                            app.pid, SystemClock.elapsedRealtime());
17991                }
17992                app.lastCpuTime = app.curCpuTime;
17993
17994            }
17995            app.setProcState = app.curProcState;
17996            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17997                app.notCachedSinceIdle = false;
17998            }
17999            if (!doingAll) {
18000                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18001            } else {
18002                app.procStateChanged = true;
18003            }
18004        }
18005
18006        if (changes != 0) {
18007            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18008            int i = mPendingProcessChanges.size()-1;
18009            ProcessChangeItem item = null;
18010            while (i >= 0) {
18011                item = mPendingProcessChanges.get(i);
18012                if (item.pid == app.pid) {
18013                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18014                    break;
18015                }
18016                i--;
18017            }
18018            if (i < 0) {
18019                // No existing item in pending changes; need a new one.
18020                final int NA = mAvailProcessChanges.size();
18021                if (NA > 0) {
18022                    item = mAvailProcessChanges.remove(NA-1);
18023                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18024                } else {
18025                    item = new ProcessChangeItem();
18026                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18027                }
18028                item.changes = 0;
18029                item.pid = app.pid;
18030                item.uid = app.info.uid;
18031                if (mPendingProcessChanges.size() == 0) {
18032                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18033                            "*** Enqueueing dispatch processes changed!");
18034                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18035                }
18036                mPendingProcessChanges.add(item);
18037            }
18038            item.changes |= changes;
18039            item.processState = app.repProcState;
18040            item.foregroundActivities = app.repForegroundActivities;
18041            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18042                    + Integer.toHexString(System.identityHashCode(item))
18043                    + " " + app.toShortString() + ": changes=" + item.changes
18044                    + " procState=" + item.processState
18045                    + " foreground=" + item.foregroundActivities
18046                    + " type=" + app.adjType + " source=" + app.adjSource
18047                    + " target=" + app.adjTarget);
18048        }
18049
18050        return success;
18051    }
18052
18053    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18054        if (proc.thread != null) {
18055            if (proc.baseProcessTracker != null) {
18056                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18057            }
18058            if (proc.repProcState >= 0) {
18059                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18060                        proc.repProcState);
18061            }
18062        }
18063    }
18064
18065    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18066            ProcessRecord TOP_APP, boolean doingAll, long now) {
18067        if (app.thread == null) {
18068            return false;
18069        }
18070
18071        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18072
18073        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18074    }
18075
18076    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18077            boolean oomAdj) {
18078        if (isForeground != proc.foregroundServices) {
18079            proc.foregroundServices = isForeground;
18080            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18081                    proc.info.uid);
18082            if (isForeground) {
18083                if (curProcs == null) {
18084                    curProcs = new ArrayList<ProcessRecord>();
18085                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18086                }
18087                if (!curProcs.contains(proc)) {
18088                    curProcs.add(proc);
18089                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18090                            proc.info.packageName, proc.info.uid);
18091                }
18092            } else {
18093                if (curProcs != null) {
18094                    if (curProcs.remove(proc)) {
18095                        mBatteryStatsService.noteEvent(
18096                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18097                                proc.info.packageName, proc.info.uid);
18098                        if (curProcs.size() <= 0) {
18099                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18100                        }
18101                    }
18102                }
18103            }
18104            if (oomAdj) {
18105                updateOomAdjLocked();
18106            }
18107        }
18108    }
18109
18110    private final ActivityRecord resumedAppLocked() {
18111        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18112        String pkg;
18113        int uid;
18114        if (act != null) {
18115            pkg = act.packageName;
18116            uid = act.info.applicationInfo.uid;
18117        } else {
18118            pkg = null;
18119            uid = -1;
18120        }
18121        // Has the UID or resumed package name changed?
18122        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18123                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18124            if (mCurResumedPackage != null) {
18125                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18126                        mCurResumedPackage, mCurResumedUid);
18127            }
18128            mCurResumedPackage = pkg;
18129            mCurResumedUid = uid;
18130            if (mCurResumedPackage != null) {
18131                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18132                        mCurResumedPackage, mCurResumedUid);
18133            }
18134        }
18135        return act;
18136    }
18137
18138    final boolean updateOomAdjLocked(ProcessRecord app) {
18139        final ActivityRecord TOP_ACT = resumedAppLocked();
18140        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18141        final boolean wasCached = app.cached;
18142
18143        mAdjSeq++;
18144
18145        // This is the desired cached adjusment we want to tell it to use.
18146        // If our app is currently cached, we know it, and that is it.  Otherwise,
18147        // we don't know it yet, and it needs to now be cached we will then
18148        // need to do a complete oom adj.
18149        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18150                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18151        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18152                SystemClock.uptimeMillis());
18153        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18154            // Changed to/from cached state, so apps after it in the LRU
18155            // list may also be changed.
18156            updateOomAdjLocked();
18157        }
18158        return success;
18159    }
18160
18161    final void updateOomAdjLocked() {
18162        final ActivityRecord TOP_ACT = resumedAppLocked();
18163        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18164        final long now = SystemClock.uptimeMillis();
18165        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18166        final int N = mLruProcesses.size();
18167
18168        if (false) {
18169            RuntimeException e = new RuntimeException();
18170            e.fillInStackTrace();
18171            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18172        }
18173
18174        mAdjSeq++;
18175        mNewNumServiceProcs = 0;
18176        mNewNumAServiceProcs = 0;
18177
18178        final int emptyProcessLimit;
18179        final int cachedProcessLimit;
18180        if (mProcessLimit <= 0) {
18181            emptyProcessLimit = cachedProcessLimit = 0;
18182        } else if (mProcessLimit == 1) {
18183            emptyProcessLimit = 1;
18184            cachedProcessLimit = 0;
18185        } else {
18186            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18187            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18188        }
18189
18190        // Let's determine how many processes we have running vs.
18191        // how many slots we have for background processes; we may want
18192        // to put multiple processes in a slot of there are enough of
18193        // them.
18194        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18195                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18196        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18197        if (numEmptyProcs > cachedProcessLimit) {
18198            // If there are more empty processes than our limit on cached
18199            // processes, then use the cached process limit for the factor.
18200            // This ensures that the really old empty processes get pushed
18201            // down to the bottom, so if we are running low on memory we will
18202            // have a better chance at keeping around more cached processes
18203            // instead of a gazillion empty processes.
18204            numEmptyProcs = cachedProcessLimit;
18205        }
18206        int emptyFactor = numEmptyProcs/numSlots;
18207        if (emptyFactor < 1) emptyFactor = 1;
18208        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18209        if (cachedFactor < 1) cachedFactor = 1;
18210        int stepCached = 0;
18211        int stepEmpty = 0;
18212        int numCached = 0;
18213        int numEmpty = 0;
18214        int numTrimming = 0;
18215
18216        mNumNonCachedProcs = 0;
18217        mNumCachedHiddenProcs = 0;
18218
18219        // First update the OOM adjustment for each of the
18220        // application processes based on their current state.
18221        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18222        int nextCachedAdj = curCachedAdj+1;
18223        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18224        int nextEmptyAdj = curEmptyAdj+2;
18225        for (int i=N-1; i>=0; i--) {
18226            ProcessRecord app = mLruProcesses.get(i);
18227            if (!app.killedByAm && app.thread != null) {
18228                app.procStateChanged = false;
18229                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18230
18231                // If we haven't yet assigned the final cached adj
18232                // to the process, do that now.
18233                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18234                    switch (app.curProcState) {
18235                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18236                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18237                            // This process is a cached process holding activities...
18238                            // assign it the next cached value for that type, and then
18239                            // step that cached level.
18240                            app.curRawAdj = curCachedAdj;
18241                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18242                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18243                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18244                                    + ")");
18245                            if (curCachedAdj != nextCachedAdj) {
18246                                stepCached++;
18247                                if (stepCached >= cachedFactor) {
18248                                    stepCached = 0;
18249                                    curCachedAdj = nextCachedAdj;
18250                                    nextCachedAdj += 2;
18251                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18252                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18253                                    }
18254                                }
18255                            }
18256                            break;
18257                        default:
18258                            // For everything else, assign next empty cached process
18259                            // level and bump that up.  Note that this means that
18260                            // long-running services that have dropped down to the
18261                            // cached level will be treated as empty (since their process
18262                            // state is still as a service), which is what we want.
18263                            app.curRawAdj = curEmptyAdj;
18264                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18265                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18266                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18267                                    + ")");
18268                            if (curEmptyAdj != nextEmptyAdj) {
18269                                stepEmpty++;
18270                                if (stepEmpty >= emptyFactor) {
18271                                    stepEmpty = 0;
18272                                    curEmptyAdj = nextEmptyAdj;
18273                                    nextEmptyAdj += 2;
18274                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18275                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18276                                    }
18277                                }
18278                            }
18279                            break;
18280                    }
18281                }
18282
18283                applyOomAdjLocked(app, TOP_APP, true, now);
18284
18285                // Count the number of process types.
18286                switch (app.curProcState) {
18287                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18288                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18289                        mNumCachedHiddenProcs++;
18290                        numCached++;
18291                        if (numCached > cachedProcessLimit) {
18292                            app.kill("cached #" + numCached, true);
18293                        }
18294                        break;
18295                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18296                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18297                                && app.lastActivityTime < oldTime) {
18298                            app.kill("empty for "
18299                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18300                                    / 1000) + "s", true);
18301                        } else {
18302                            numEmpty++;
18303                            if (numEmpty > emptyProcessLimit) {
18304                                app.kill("empty #" + numEmpty, true);
18305                            }
18306                        }
18307                        break;
18308                    default:
18309                        mNumNonCachedProcs++;
18310                        break;
18311                }
18312
18313                if (app.isolated && app.services.size() <= 0) {
18314                    // If this is an isolated process, and there are no
18315                    // services running in it, then the process is no longer
18316                    // needed.  We agressively kill these because we can by
18317                    // definition not re-use the same process again, and it is
18318                    // good to avoid having whatever code was running in them
18319                    // left sitting around after no longer needed.
18320                    app.kill("isolated not needed", true);
18321                }
18322
18323                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18324                        && !app.killedByAm) {
18325                    numTrimming++;
18326                }
18327            }
18328        }
18329
18330        mNumServiceProcs = mNewNumServiceProcs;
18331
18332        // Now determine the memory trimming level of background processes.
18333        // Unfortunately we need to start at the back of the list to do this
18334        // properly.  We only do this if the number of background apps we
18335        // are managing to keep around is less than half the maximum we desire;
18336        // if we are keeping a good number around, we'll let them use whatever
18337        // memory they want.
18338        final int numCachedAndEmpty = numCached + numEmpty;
18339        int memFactor;
18340        if (numCached <= ProcessList.TRIM_CACHED_APPS
18341                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18342            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18343                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18344            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18345                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18346            } else {
18347                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18348            }
18349        } else {
18350            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18351        }
18352        // We always allow the memory level to go up (better).  We only allow it to go
18353        // down if we are in a state where that is allowed, *and* the total number of processes
18354        // has gone down since last time.
18355        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18356                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18357                + " last=" + mLastNumProcesses);
18358        if (memFactor > mLastMemoryLevel) {
18359            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18360                memFactor = mLastMemoryLevel;
18361                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18362            }
18363        }
18364        mLastMemoryLevel = memFactor;
18365        mLastNumProcesses = mLruProcesses.size();
18366        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18367        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18368        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18369            if (mLowRamStartTime == 0) {
18370                mLowRamStartTime = now;
18371            }
18372            int step = 0;
18373            int fgTrimLevel;
18374            switch (memFactor) {
18375                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18376                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18377                    break;
18378                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18379                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18380                    break;
18381                default:
18382                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18383                    break;
18384            }
18385            int factor = numTrimming/3;
18386            int minFactor = 2;
18387            if (mHomeProcess != null) minFactor++;
18388            if (mPreviousProcess != null) minFactor++;
18389            if (factor < minFactor) factor = minFactor;
18390            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18391            for (int i=N-1; i>=0; i--) {
18392                ProcessRecord app = mLruProcesses.get(i);
18393                if (allChanged || app.procStateChanged) {
18394                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18395                    app.procStateChanged = false;
18396                }
18397                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18398                        && !app.killedByAm) {
18399                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18400                        try {
18401                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18402                                    "Trimming memory of " + app.processName
18403                                    + " to " + curLevel);
18404                            app.thread.scheduleTrimMemory(curLevel);
18405                        } catch (RemoteException e) {
18406                        }
18407                        if (false) {
18408                            // For now we won't do this; our memory trimming seems
18409                            // to be good enough at this point that destroying
18410                            // activities causes more harm than good.
18411                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18412                                    && app != mHomeProcess && app != mPreviousProcess) {
18413                                // Need to do this on its own message because the stack may not
18414                                // be in a consistent state at this point.
18415                                // For these apps we will also finish their activities
18416                                // to help them free memory.
18417                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18418                            }
18419                        }
18420                    }
18421                    app.trimMemoryLevel = curLevel;
18422                    step++;
18423                    if (step >= factor) {
18424                        step = 0;
18425                        switch (curLevel) {
18426                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18427                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18428                                break;
18429                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18430                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18431                                break;
18432                        }
18433                    }
18434                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18435                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18436                            && app.thread != null) {
18437                        try {
18438                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18439                                    "Trimming memory of heavy-weight " + app.processName
18440                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18441                            app.thread.scheduleTrimMemory(
18442                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18443                        } catch (RemoteException e) {
18444                        }
18445                    }
18446                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18447                } else {
18448                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18449                            || app.systemNoUi) && app.pendingUiClean) {
18450                        // If this application is now in the background and it
18451                        // had done UI, then give it the special trim level to
18452                        // have it free UI resources.
18453                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18454                        if (app.trimMemoryLevel < level && app.thread != null) {
18455                            try {
18456                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18457                                        "Trimming memory of bg-ui " + app.processName
18458                                        + " to " + level);
18459                                app.thread.scheduleTrimMemory(level);
18460                            } catch (RemoteException e) {
18461                            }
18462                        }
18463                        app.pendingUiClean = false;
18464                    }
18465                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18466                        try {
18467                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18468                                    "Trimming memory of fg " + app.processName
18469                                    + " to " + fgTrimLevel);
18470                            app.thread.scheduleTrimMemory(fgTrimLevel);
18471                        } catch (RemoteException e) {
18472                        }
18473                    }
18474                    app.trimMemoryLevel = fgTrimLevel;
18475                }
18476            }
18477        } else {
18478            if (mLowRamStartTime != 0) {
18479                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18480                mLowRamStartTime = 0;
18481            }
18482            for (int i=N-1; i>=0; i--) {
18483                ProcessRecord app = mLruProcesses.get(i);
18484                if (allChanged || app.procStateChanged) {
18485                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18486                    app.procStateChanged = false;
18487                }
18488                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18489                        || app.systemNoUi) && app.pendingUiClean) {
18490                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18491                            && app.thread != null) {
18492                        try {
18493                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18494                                    "Trimming memory of ui hidden " + app.processName
18495                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18496                            app.thread.scheduleTrimMemory(
18497                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18498                        } catch (RemoteException e) {
18499                        }
18500                    }
18501                    app.pendingUiClean = false;
18502                }
18503                app.trimMemoryLevel = 0;
18504            }
18505        }
18506
18507        if (mAlwaysFinishActivities) {
18508            // Need to do this on its own message because the stack may not
18509            // be in a consistent state at this point.
18510            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18511        }
18512
18513        if (allChanged) {
18514            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18515        }
18516
18517        if (mProcessStats.shouldWriteNowLocked(now)) {
18518            mHandler.post(new Runnable() {
18519                @Override public void run() {
18520                    synchronized (ActivityManagerService.this) {
18521                        mProcessStats.writeStateAsyncLocked();
18522                    }
18523                }
18524            });
18525        }
18526
18527        if (DEBUG_OOM_ADJ) {
18528            if (false) {
18529                RuntimeException here = new RuntimeException("here");
18530                here.fillInStackTrace();
18531                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18532            } else {
18533                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18534            }
18535        }
18536    }
18537
18538    final void trimApplications() {
18539        synchronized (this) {
18540            int i;
18541
18542            // First remove any unused application processes whose package
18543            // has been removed.
18544            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18545                final ProcessRecord app = mRemovedProcesses.get(i);
18546                if (app.activities.size() == 0
18547                        && app.curReceiver == null && app.services.size() == 0) {
18548                    Slog.i(
18549                        TAG, "Exiting empty application process "
18550                        + app.processName + " ("
18551                        + (app.thread != null ? app.thread.asBinder() : null)
18552                        + ")\n");
18553                    if (app.pid > 0 && app.pid != MY_PID) {
18554                        app.kill("empty", false);
18555                    } else {
18556                        try {
18557                            app.thread.scheduleExit();
18558                        } catch (Exception e) {
18559                            // Ignore exceptions.
18560                        }
18561                    }
18562                    cleanUpApplicationRecordLocked(app, false, true, -1);
18563                    mRemovedProcesses.remove(i);
18564
18565                    if (app.persistent) {
18566                        addAppLocked(app.info, false, null /* ABI override */);
18567                    }
18568                }
18569            }
18570
18571            // Now update the oom adj for all processes.
18572            updateOomAdjLocked();
18573        }
18574    }
18575
18576    /** This method sends the specified signal to each of the persistent apps */
18577    public void signalPersistentProcesses(int sig) throws RemoteException {
18578        if (sig != Process.SIGNAL_USR1) {
18579            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18580        }
18581
18582        synchronized (this) {
18583            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18584                    != PackageManager.PERMISSION_GRANTED) {
18585                throw new SecurityException("Requires permission "
18586                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18587            }
18588
18589            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18590                ProcessRecord r = mLruProcesses.get(i);
18591                if (r.thread != null && r.persistent) {
18592                    Process.sendSignal(r.pid, sig);
18593                }
18594            }
18595        }
18596    }
18597
18598    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18599        if (proc == null || proc == mProfileProc) {
18600            proc = mProfileProc;
18601            profileType = mProfileType;
18602            clearProfilerLocked();
18603        }
18604        if (proc == null) {
18605            return;
18606        }
18607        try {
18608            proc.thread.profilerControl(false, null, profileType);
18609        } catch (RemoteException e) {
18610            throw new IllegalStateException("Process disappeared");
18611        }
18612    }
18613
18614    private void clearProfilerLocked() {
18615        if (mProfileFd != null) {
18616            try {
18617                mProfileFd.close();
18618            } catch (IOException e) {
18619            }
18620        }
18621        mProfileApp = null;
18622        mProfileProc = null;
18623        mProfileFile = null;
18624        mProfileType = 0;
18625        mAutoStopProfiler = false;
18626        mSamplingInterval = 0;
18627    }
18628
18629    public boolean profileControl(String process, int userId, boolean start,
18630            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18631
18632        try {
18633            synchronized (this) {
18634                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18635                // its own permission.
18636                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18637                        != PackageManager.PERMISSION_GRANTED) {
18638                    throw new SecurityException("Requires permission "
18639                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18640                }
18641
18642                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18643                    throw new IllegalArgumentException("null profile info or fd");
18644                }
18645
18646                ProcessRecord proc = null;
18647                if (process != null) {
18648                    proc = findProcessLocked(process, userId, "profileControl");
18649                }
18650
18651                if (start && (proc == null || proc.thread == null)) {
18652                    throw new IllegalArgumentException("Unknown process: " + process);
18653                }
18654
18655                if (start) {
18656                    stopProfilerLocked(null, 0);
18657                    setProfileApp(proc.info, proc.processName, profilerInfo);
18658                    mProfileProc = proc;
18659                    mProfileType = profileType;
18660                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18661                    try {
18662                        fd = fd.dup();
18663                    } catch (IOException e) {
18664                        fd = null;
18665                    }
18666                    profilerInfo.profileFd = fd;
18667                    proc.thread.profilerControl(start, profilerInfo, profileType);
18668                    fd = null;
18669                    mProfileFd = null;
18670                } else {
18671                    stopProfilerLocked(proc, profileType);
18672                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18673                        try {
18674                            profilerInfo.profileFd.close();
18675                        } catch (IOException e) {
18676                        }
18677                    }
18678                }
18679
18680                return true;
18681            }
18682        } catch (RemoteException e) {
18683            throw new IllegalStateException("Process disappeared");
18684        } finally {
18685            if (profilerInfo != null && profilerInfo.profileFd != null) {
18686                try {
18687                    profilerInfo.profileFd.close();
18688                } catch (IOException e) {
18689                }
18690            }
18691        }
18692    }
18693
18694    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18696                userId, true, ALLOW_FULL_ONLY, callName, null);
18697        ProcessRecord proc = null;
18698        try {
18699            int pid = Integer.parseInt(process);
18700            synchronized (mPidsSelfLocked) {
18701                proc = mPidsSelfLocked.get(pid);
18702            }
18703        } catch (NumberFormatException e) {
18704        }
18705
18706        if (proc == null) {
18707            ArrayMap<String, SparseArray<ProcessRecord>> all
18708                    = mProcessNames.getMap();
18709            SparseArray<ProcessRecord> procs = all.get(process);
18710            if (procs != null && procs.size() > 0) {
18711                proc = procs.valueAt(0);
18712                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18713                    for (int i=1; i<procs.size(); i++) {
18714                        ProcessRecord thisProc = procs.valueAt(i);
18715                        if (thisProc.userId == userId) {
18716                            proc = thisProc;
18717                            break;
18718                        }
18719                    }
18720                }
18721            }
18722        }
18723
18724        return proc;
18725    }
18726
18727    public boolean dumpHeap(String process, int userId, boolean managed,
18728            String path, ParcelFileDescriptor fd) throws RemoteException {
18729
18730        try {
18731            synchronized (this) {
18732                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18733                // its own permission (same as profileControl).
18734                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18735                        != PackageManager.PERMISSION_GRANTED) {
18736                    throw new SecurityException("Requires permission "
18737                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18738                }
18739
18740                if (fd == null) {
18741                    throw new IllegalArgumentException("null fd");
18742                }
18743
18744                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18745                if (proc == null || proc.thread == null) {
18746                    throw new IllegalArgumentException("Unknown process: " + process);
18747                }
18748
18749                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18750                if (!isDebuggable) {
18751                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18752                        throw new SecurityException("Process not debuggable: " + proc);
18753                    }
18754                }
18755
18756                proc.thread.dumpHeap(managed, path, fd);
18757                fd = null;
18758                return true;
18759            }
18760        } catch (RemoteException e) {
18761            throw new IllegalStateException("Process disappeared");
18762        } finally {
18763            if (fd != null) {
18764                try {
18765                    fd.close();
18766                } catch (IOException e) {
18767                }
18768            }
18769        }
18770    }
18771
18772    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18773    public void monitor() {
18774        synchronized (this) { }
18775    }
18776
18777    void onCoreSettingsChange(Bundle settings) {
18778        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18779            ProcessRecord processRecord = mLruProcesses.get(i);
18780            try {
18781                if (processRecord.thread != null) {
18782                    processRecord.thread.setCoreSettings(settings);
18783                }
18784            } catch (RemoteException re) {
18785                /* ignore */
18786            }
18787        }
18788    }
18789
18790    // Multi-user methods
18791
18792    /**
18793     * Start user, if its not already running, but don't bring it to foreground.
18794     */
18795    @Override
18796    public boolean startUserInBackground(final int userId) {
18797        return startUser(userId, /* foreground */ false);
18798    }
18799
18800    /**
18801     * Start user, if its not already running, and bring it to foreground.
18802     */
18803    boolean startUserInForeground(final int userId, Dialog dlg) {
18804        boolean result = startUser(userId, /* foreground */ true);
18805        dlg.dismiss();
18806        return result;
18807    }
18808
18809    /**
18810     * Refreshes the list of users related to the current user when either a
18811     * user switch happens or when a new related user is started in the
18812     * background.
18813     */
18814    private void updateCurrentProfileIdsLocked() {
18815        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18816                mCurrentUserId, false /* enabledOnly */);
18817        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18818        for (int i = 0; i < currentProfileIds.length; i++) {
18819            currentProfileIds[i] = profiles.get(i).id;
18820        }
18821        mCurrentProfileIds = currentProfileIds;
18822
18823        synchronized (mUserProfileGroupIdsSelfLocked) {
18824            mUserProfileGroupIdsSelfLocked.clear();
18825            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18826            for (int i = 0; i < users.size(); i++) {
18827                UserInfo user = users.get(i);
18828                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18829                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18830                }
18831            }
18832        }
18833    }
18834
18835    private Set getProfileIdsLocked(int userId) {
18836        Set userIds = new HashSet<Integer>();
18837        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18838                userId, false /* enabledOnly */);
18839        for (UserInfo user : profiles) {
18840            userIds.add(Integer.valueOf(user.id));
18841        }
18842        return userIds;
18843    }
18844
18845    @Override
18846    public boolean switchUser(final int userId) {
18847        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18848        String userName;
18849        synchronized (this) {
18850            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18851            if (userInfo == null) {
18852                Slog.w(TAG, "No user info for user #" + userId);
18853                return false;
18854            }
18855            if (userInfo.isManagedProfile()) {
18856                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18857                return false;
18858            }
18859            userName = userInfo.name;
18860            mTargetUserId = userId;
18861        }
18862        mHandler.removeMessages(START_USER_SWITCH_MSG);
18863        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18864        return true;
18865    }
18866
18867    private void showUserSwitchDialog(int userId, String userName) {
18868        // The dialog will show and then initiate the user switch by calling startUserInForeground
18869        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18870                true /* above system */);
18871        d.show();
18872    }
18873
18874    private boolean startUser(final int userId, final boolean foreground) {
18875        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18876                != PackageManager.PERMISSION_GRANTED) {
18877            String msg = "Permission Denial: switchUser() from pid="
18878                    + Binder.getCallingPid()
18879                    + ", uid=" + Binder.getCallingUid()
18880                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18881            Slog.w(TAG, msg);
18882            throw new SecurityException(msg);
18883        }
18884
18885        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18886
18887        final long ident = Binder.clearCallingIdentity();
18888        try {
18889            synchronized (this) {
18890                final int oldUserId = mCurrentUserId;
18891                if (oldUserId == userId) {
18892                    return true;
18893                }
18894
18895                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18896
18897                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18898                if (userInfo == null) {
18899                    Slog.w(TAG, "No user info for user #" + userId);
18900                    return false;
18901                }
18902                if (foreground && userInfo.isManagedProfile()) {
18903                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18904                    return false;
18905                }
18906
18907                if (foreground) {
18908                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18909                            R.anim.screen_user_enter);
18910                }
18911
18912                boolean needStart = false;
18913
18914                // If the user we are switching to is not currently started, then
18915                // we need to start it now.
18916                if (mStartedUsers.get(userId) == null) {
18917                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18918                    updateStartedUserArrayLocked();
18919                    needStart = true;
18920                }
18921
18922                final Integer userIdInt = Integer.valueOf(userId);
18923                mUserLru.remove(userIdInt);
18924                mUserLru.add(userIdInt);
18925
18926                if (foreground) {
18927                    mCurrentUserId = userId;
18928                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18929                    updateCurrentProfileIdsLocked();
18930                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18931                    // Once the internal notion of the active user has switched, we lock the device
18932                    // with the option to show the user switcher on the keyguard.
18933                    mWindowManager.lockNow(null);
18934                } else {
18935                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18936                    updateCurrentProfileIdsLocked();
18937                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18938                    mUserLru.remove(currentUserIdInt);
18939                    mUserLru.add(currentUserIdInt);
18940                }
18941
18942                final UserStartedState uss = mStartedUsers.get(userId);
18943
18944                // Make sure user is in the started state.  If it is currently
18945                // stopping, we need to knock that off.
18946                if (uss.mState == UserStartedState.STATE_STOPPING) {
18947                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18948                    // so we can just fairly silently bring the user back from
18949                    // the almost-dead.
18950                    uss.mState = UserStartedState.STATE_RUNNING;
18951                    updateStartedUserArrayLocked();
18952                    needStart = true;
18953                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18954                    // This means ACTION_SHUTDOWN has been sent, so we will
18955                    // need to treat this as a new boot of the user.
18956                    uss.mState = UserStartedState.STATE_BOOTING;
18957                    updateStartedUserArrayLocked();
18958                    needStart = true;
18959                }
18960
18961                if (uss.mState == UserStartedState.STATE_BOOTING) {
18962                    // Booting up a new user, need to tell system services about it.
18963                    // Note that this is on the same handler as scheduling of broadcasts,
18964                    // which is important because it needs to go first.
18965                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18966                }
18967
18968                if (foreground) {
18969                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18970                            oldUserId));
18971                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18972                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18973                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18974                            oldUserId, userId, uss));
18975                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18976                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18977                }
18978
18979                if (needStart) {
18980                    // Send USER_STARTED broadcast
18981                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18982                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18983                            | Intent.FLAG_RECEIVER_FOREGROUND);
18984                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18985                    broadcastIntentLocked(null, null, intent,
18986                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18987                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18988                }
18989
18990                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18991                    if (userId != UserHandle.USER_OWNER) {
18992                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18993                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18994                        broadcastIntentLocked(null, null, intent, null,
18995                                new IIntentReceiver.Stub() {
18996                                    public void performReceive(Intent intent, int resultCode,
18997                                            String data, Bundle extras, boolean ordered,
18998                                            boolean sticky, int sendingUser) {
18999                                        onUserInitialized(uss, foreground, oldUserId, userId);
19000                                    }
19001                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19002                                true, false, MY_PID, Process.SYSTEM_UID,
19003                                userId);
19004                        uss.initializing = true;
19005                    } else {
19006                        getUserManagerLocked().makeInitialized(userInfo.id);
19007                    }
19008                }
19009
19010                if (foreground) {
19011                    if (!uss.initializing) {
19012                        moveUserToForeground(uss, oldUserId, userId);
19013                    }
19014                } else {
19015                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19016                }
19017
19018                if (needStart) {
19019                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19020                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19021                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19022                    broadcastIntentLocked(null, null, intent,
19023                            null, 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                                        throws RemoteException {
19028                                }
19029                            }, 0, null, null,
19030                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19031                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19032                }
19033            }
19034        } finally {
19035            Binder.restoreCallingIdentity(ident);
19036        }
19037
19038        return true;
19039    }
19040
19041    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19042        long ident = Binder.clearCallingIdentity();
19043        try {
19044            Intent intent;
19045            if (oldUserId >= 0) {
19046                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19047                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19048                int count = profiles.size();
19049                for (int i = 0; i < count; i++) {
19050                    int profileUserId = profiles.get(i).id;
19051                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19052                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19053                            | Intent.FLAG_RECEIVER_FOREGROUND);
19054                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19055                    broadcastIntentLocked(null, null, intent,
19056                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19057                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19058                }
19059            }
19060            if (newUserId >= 0) {
19061                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19062                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19063                int count = profiles.size();
19064                for (int i = 0; i < count; i++) {
19065                    int profileUserId = profiles.get(i).id;
19066                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19067                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19068                            | Intent.FLAG_RECEIVER_FOREGROUND);
19069                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19070                    broadcastIntentLocked(null, null, intent,
19071                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19072                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19073                }
19074                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19075                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19076                        | Intent.FLAG_RECEIVER_FOREGROUND);
19077                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19078                broadcastIntentLocked(null, null, intent,
19079                        null, null, 0, null, null,
19080                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19081                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19082            }
19083        } finally {
19084            Binder.restoreCallingIdentity(ident);
19085        }
19086    }
19087
19088    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19089            final int newUserId) {
19090        final int N = mUserSwitchObservers.beginBroadcast();
19091        if (N > 0) {
19092            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19093                int mCount = 0;
19094                @Override
19095                public void sendResult(Bundle data) throws RemoteException {
19096                    synchronized (ActivityManagerService.this) {
19097                        if (mCurUserSwitchCallback == this) {
19098                            mCount++;
19099                            if (mCount == N) {
19100                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19101                            }
19102                        }
19103                    }
19104                }
19105            };
19106            synchronized (this) {
19107                uss.switching = true;
19108                mCurUserSwitchCallback = callback;
19109            }
19110            for (int i=0; i<N; i++) {
19111                try {
19112                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19113                            newUserId, callback);
19114                } catch (RemoteException e) {
19115                }
19116            }
19117        } else {
19118            synchronized (this) {
19119                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19120            }
19121        }
19122        mUserSwitchObservers.finishBroadcast();
19123    }
19124
19125    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19126        synchronized (this) {
19127            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19128            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19129        }
19130    }
19131
19132    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19133        mCurUserSwitchCallback = null;
19134        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19135        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19136                oldUserId, newUserId, uss));
19137    }
19138
19139    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19140        synchronized (this) {
19141            if (foreground) {
19142                moveUserToForeground(uss, oldUserId, newUserId);
19143            }
19144        }
19145
19146        completeSwitchAndInitalize(uss, newUserId, true, false);
19147    }
19148
19149    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19150        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19151        if (homeInFront) {
19152            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19153        } else {
19154            mStackSupervisor.resumeTopActivitiesLocked();
19155        }
19156        EventLogTags.writeAmSwitchUser(newUserId);
19157        getUserManagerLocked().userForeground(newUserId);
19158        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19159    }
19160
19161    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19162        completeSwitchAndInitalize(uss, newUserId, false, true);
19163    }
19164
19165    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19166            boolean clearInitializing, boolean clearSwitching) {
19167        boolean unfrozen = false;
19168        synchronized (this) {
19169            if (clearInitializing) {
19170                uss.initializing = false;
19171                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19172            }
19173            if (clearSwitching) {
19174                uss.switching = false;
19175            }
19176            if (!uss.switching && !uss.initializing) {
19177                mWindowManager.stopFreezingScreen();
19178                unfrozen = true;
19179            }
19180        }
19181        if (unfrozen) {
19182            final int N = mUserSwitchObservers.beginBroadcast();
19183            for (int i=0; i<N; i++) {
19184                try {
19185                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19186                } catch (RemoteException e) {
19187                }
19188            }
19189            mUserSwitchObservers.finishBroadcast();
19190        }
19191        stopGuestUserIfBackground();
19192    }
19193
19194    /**
19195     * Stops the guest user if it has gone to the background.
19196     */
19197    private void stopGuestUserIfBackground() {
19198        synchronized (this) {
19199            final int num = mUserLru.size();
19200            for (int i = 0; i < num; i++) {
19201                Integer oldUserId = mUserLru.get(i);
19202                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19203                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19204                        || oldUss.mState == UserStartedState.STATE_STOPPING
19205                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19206                    continue;
19207                }
19208                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19209                if (userInfo.isGuest()) {
19210                    // This is a user to be stopped.
19211                    stopUserLocked(oldUserId, null);
19212                    break;
19213                }
19214            }
19215        }
19216    }
19217
19218    void scheduleStartProfilesLocked() {
19219        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19220            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19221                    DateUtils.SECOND_IN_MILLIS);
19222        }
19223    }
19224
19225    void startProfilesLocked() {
19226        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19227        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19228                mCurrentUserId, false /* enabledOnly */);
19229        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19230        for (UserInfo user : profiles) {
19231            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19232                    && user.id != mCurrentUserId) {
19233                toStart.add(user);
19234            }
19235        }
19236        final int n = toStart.size();
19237        int i = 0;
19238        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19239            startUserInBackground(toStart.get(i).id);
19240        }
19241        if (i < n) {
19242            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19243        }
19244    }
19245
19246    void finishUserBoot(UserStartedState uss) {
19247        synchronized (this) {
19248            if (uss.mState == UserStartedState.STATE_BOOTING
19249                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19250                uss.mState = UserStartedState.STATE_RUNNING;
19251                final int userId = uss.mHandle.getIdentifier();
19252                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19253                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19254                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19255                broadcastIntentLocked(null, null, intent,
19256                        null, null, 0, null, null,
19257                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19258                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19259            }
19260        }
19261    }
19262
19263    void finishUserSwitch(UserStartedState uss) {
19264        synchronized (this) {
19265            finishUserBoot(uss);
19266
19267            startProfilesLocked();
19268
19269            int num = mUserLru.size();
19270            int i = 0;
19271            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19272                Integer oldUserId = mUserLru.get(i);
19273                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19274                if (oldUss == null) {
19275                    // Shouldn't happen, but be sane if it does.
19276                    mUserLru.remove(i);
19277                    num--;
19278                    continue;
19279                }
19280                if (oldUss.mState == UserStartedState.STATE_STOPPING
19281                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19282                    // This user is already stopping, doesn't count.
19283                    num--;
19284                    i++;
19285                    continue;
19286                }
19287                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19288                    // Owner and current can't be stopped, but count as running.
19289                    i++;
19290                    continue;
19291                }
19292                // This is a user to be stopped.
19293                stopUserLocked(oldUserId, null);
19294                num--;
19295                i++;
19296            }
19297        }
19298    }
19299
19300    @Override
19301    public int stopUser(final int userId, final IStopUserCallback callback) {
19302        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19303                != PackageManager.PERMISSION_GRANTED) {
19304            String msg = "Permission Denial: switchUser() from pid="
19305                    + Binder.getCallingPid()
19306                    + ", uid=" + Binder.getCallingUid()
19307                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19308            Slog.w(TAG, msg);
19309            throw new SecurityException(msg);
19310        }
19311        if (userId <= 0) {
19312            throw new IllegalArgumentException("Can't stop primary user " + userId);
19313        }
19314        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19315        synchronized (this) {
19316            return stopUserLocked(userId, callback);
19317        }
19318    }
19319
19320    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19321        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19322        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19323            return ActivityManager.USER_OP_IS_CURRENT;
19324        }
19325
19326        final UserStartedState uss = mStartedUsers.get(userId);
19327        if (uss == null) {
19328            // User is not started, nothing to do...  but we do need to
19329            // callback if requested.
19330            if (callback != null) {
19331                mHandler.post(new Runnable() {
19332                    @Override
19333                    public void run() {
19334                        try {
19335                            callback.userStopped(userId);
19336                        } catch (RemoteException e) {
19337                        }
19338                    }
19339                });
19340            }
19341            return ActivityManager.USER_OP_SUCCESS;
19342        }
19343
19344        if (callback != null) {
19345            uss.mStopCallbacks.add(callback);
19346        }
19347
19348        if (uss.mState != UserStartedState.STATE_STOPPING
19349                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19350            uss.mState = UserStartedState.STATE_STOPPING;
19351            updateStartedUserArrayLocked();
19352
19353            long ident = Binder.clearCallingIdentity();
19354            try {
19355                // We are going to broadcast ACTION_USER_STOPPING and then
19356                // once that is done send a final ACTION_SHUTDOWN and then
19357                // stop the user.
19358                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19359                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19360                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19361                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19362                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19363                // This is the result receiver for the final shutdown broadcast.
19364                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19365                    @Override
19366                    public void performReceive(Intent intent, int resultCode, String data,
19367                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19368                        finishUserStop(uss);
19369                    }
19370                };
19371                // This is the result receiver for the initial stopping broadcast.
19372                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19373                    @Override
19374                    public void performReceive(Intent intent, int resultCode, String data,
19375                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19376                        // On to the next.
19377                        synchronized (ActivityManagerService.this) {
19378                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19379                                // Whoops, we are being started back up.  Abort, abort!
19380                                return;
19381                            }
19382                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19383                        }
19384                        mBatteryStatsService.noteEvent(
19385                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19386                                Integer.toString(userId), userId);
19387                        mSystemServiceManager.stopUser(userId);
19388                        broadcastIntentLocked(null, null, shutdownIntent,
19389                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19390                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19391                    }
19392                };
19393                // Kick things off.
19394                broadcastIntentLocked(null, null, stoppingIntent,
19395                        null, stoppingReceiver, 0, null, null,
19396                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19397                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19398            } finally {
19399                Binder.restoreCallingIdentity(ident);
19400            }
19401        }
19402
19403        return ActivityManager.USER_OP_SUCCESS;
19404    }
19405
19406    void finishUserStop(UserStartedState uss) {
19407        final int userId = uss.mHandle.getIdentifier();
19408        boolean stopped;
19409        ArrayList<IStopUserCallback> callbacks;
19410        synchronized (this) {
19411            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19412            if (mStartedUsers.get(userId) != uss) {
19413                stopped = false;
19414            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19415                stopped = false;
19416            } else {
19417                stopped = true;
19418                // User can no longer run.
19419                mStartedUsers.remove(userId);
19420                mUserLru.remove(Integer.valueOf(userId));
19421                updateStartedUserArrayLocked();
19422
19423                // Clean up all state and processes associated with the user.
19424                // Kill all the processes for the user.
19425                forceStopUserLocked(userId, "finish user");
19426            }
19427
19428            // Explicitly remove the old information in mRecentTasks.
19429            removeRecentTasksForUserLocked(userId);
19430        }
19431
19432        for (int i=0; i<callbacks.size(); i++) {
19433            try {
19434                if (stopped) callbacks.get(i).userStopped(userId);
19435                else callbacks.get(i).userStopAborted(userId);
19436            } catch (RemoteException e) {
19437            }
19438        }
19439
19440        if (stopped) {
19441            mSystemServiceManager.cleanupUser(userId);
19442            synchronized (this) {
19443                mStackSupervisor.removeUserLocked(userId);
19444            }
19445        }
19446    }
19447
19448    @Override
19449    public UserInfo getCurrentUser() {
19450        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19451                != PackageManager.PERMISSION_GRANTED) && (
19452                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19453                != PackageManager.PERMISSION_GRANTED)) {
19454            String msg = "Permission Denial: getCurrentUser() from pid="
19455                    + Binder.getCallingPid()
19456                    + ", uid=" + Binder.getCallingUid()
19457                    + " requires " + INTERACT_ACROSS_USERS;
19458            Slog.w(TAG, msg);
19459            throw new SecurityException(msg);
19460        }
19461        synchronized (this) {
19462            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19463            return getUserManagerLocked().getUserInfo(userId);
19464        }
19465    }
19466
19467    int getCurrentUserIdLocked() {
19468        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19469    }
19470
19471    @Override
19472    public boolean isUserRunning(int userId, boolean orStopped) {
19473        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19474                != PackageManager.PERMISSION_GRANTED) {
19475            String msg = "Permission Denial: isUserRunning() from pid="
19476                    + Binder.getCallingPid()
19477                    + ", uid=" + Binder.getCallingUid()
19478                    + " requires " + INTERACT_ACROSS_USERS;
19479            Slog.w(TAG, msg);
19480            throw new SecurityException(msg);
19481        }
19482        synchronized (this) {
19483            return isUserRunningLocked(userId, orStopped);
19484        }
19485    }
19486
19487    boolean isUserRunningLocked(int userId, boolean orStopped) {
19488        UserStartedState state = mStartedUsers.get(userId);
19489        if (state == null) {
19490            return false;
19491        }
19492        if (orStopped) {
19493            return true;
19494        }
19495        return state.mState != UserStartedState.STATE_STOPPING
19496                && state.mState != UserStartedState.STATE_SHUTDOWN;
19497    }
19498
19499    @Override
19500    public int[] getRunningUserIds() {
19501        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19502                != PackageManager.PERMISSION_GRANTED) {
19503            String msg = "Permission Denial: isUserRunning() from pid="
19504                    + Binder.getCallingPid()
19505                    + ", uid=" + Binder.getCallingUid()
19506                    + " requires " + INTERACT_ACROSS_USERS;
19507            Slog.w(TAG, msg);
19508            throw new SecurityException(msg);
19509        }
19510        synchronized (this) {
19511            return mStartedUserArray;
19512        }
19513    }
19514
19515    private void updateStartedUserArrayLocked() {
19516        int num = 0;
19517        for (int i=0; i<mStartedUsers.size();  i++) {
19518            UserStartedState uss = mStartedUsers.valueAt(i);
19519            // This list does not include stopping users.
19520            if (uss.mState != UserStartedState.STATE_STOPPING
19521                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19522                num++;
19523            }
19524        }
19525        mStartedUserArray = new int[num];
19526        num = 0;
19527        for (int i=0; i<mStartedUsers.size();  i++) {
19528            UserStartedState uss = mStartedUsers.valueAt(i);
19529            if (uss.mState != UserStartedState.STATE_STOPPING
19530                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19531                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19532                num++;
19533            }
19534        }
19535    }
19536
19537    @Override
19538    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19539        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19540                != PackageManager.PERMISSION_GRANTED) {
19541            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19542                    + Binder.getCallingPid()
19543                    + ", uid=" + Binder.getCallingUid()
19544                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19545            Slog.w(TAG, msg);
19546            throw new SecurityException(msg);
19547        }
19548
19549        mUserSwitchObservers.register(observer);
19550    }
19551
19552    @Override
19553    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19554        mUserSwitchObservers.unregister(observer);
19555    }
19556
19557    private boolean userExists(int userId) {
19558        if (userId == 0) {
19559            return true;
19560        }
19561        UserManagerService ums = getUserManagerLocked();
19562        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19563    }
19564
19565    int[] getUsersLocked() {
19566        UserManagerService ums = getUserManagerLocked();
19567        return ums != null ? ums.getUserIds() : new int[] { 0 };
19568    }
19569
19570    UserManagerService getUserManagerLocked() {
19571        if (mUserManager == null) {
19572            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19573            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19574        }
19575        return mUserManager;
19576    }
19577
19578    private int applyUserId(int uid, int userId) {
19579        return UserHandle.getUid(userId, uid);
19580    }
19581
19582    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19583        if (info == null) return null;
19584        ApplicationInfo newInfo = new ApplicationInfo(info);
19585        newInfo.uid = applyUserId(info.uid, userId);
19586        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19587                + info.packageName;
19588        return newInfo;
19589    }
19590
19591    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19592        if (aInfo == null
19593                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19594            return aInfo;
19595        }
19596
19597        ActivityInfo info = new ActivityInfo(aInfo);
19598        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19599        return info;
19600    }
19601
19602    private final class LocalService extends ActivityManagerInternal {
19603        @Override
19604        public void onWakefulnessChanged(int wakefulness) {
19605            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19606        }
19607
19608        @Override
19609        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19610                String processName, String abiOverride, int uid, Runnable crashHandler) {
19611            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19612                    processName, abiOverride, uid, crashHandler);
19613        }
19614    }
19615
19616    /**
19617     * An implementation of IAppTask, that allows an app to manage its own tasks via
19618     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19619     * only the process that calls getAppTasks() can call the AppTask methods.
19620     */
19621    class AppTaskImpl extends IAppTask.Stub {
19622        private int mTaskId;
19623        private int mCallingUid;
19624
19625        public AppTaskImpl(int taskId, int callingUid) {
19626            mTaskId = taskId;
19627            mCallingUid = callingUid;
19628        }
19629
19630        private void checkCaller() {
19631            if (mCallingUid != Binder.getCallingUid()) {
19632                throw new SecurityException("Caller " + mCallingUid
19633                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19634            }
19635        }
19636
19637        @Override
19638        public void finishAndRemoveTask() {
19639            checkCaller();
19640
19641            synchronized (ActivityManagerService.this) {
19642                long origId = Binder.clearCallingIdentity();
19643                try {
19644                    if (!removeTaskByIdLocked(mTaskId, false)) {
19645                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19646                    }
19647                } finally {
19648                    Binder.restoreCallingIdentity(origId);
19649                }
19650            }
19651        }
19652
19653        @Override
19654        public ActivityManager.RecentTaskInfo getTaskInfo() {
19655            checkCaller();
19656
19657            synchronized (ActivityManagerService.this) {
19658                long origId = Binder.clearCallingIdentity();
19659                try {
19660                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19661                    if (tr == null) {
19662                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19663                    }
19664                    return createRecentTaskInfoFromTaskRecord(tr);
19665                } finally {
19666                    Binder.restoreCallingIdentity(origId);
19667                }
19668            }
19669        }
19670
19671        @Override
19672        public void moveToFront() {
19673            checkCaller();
19674            // Will bring task to front if it already has a root activity.
19675            startActivityFromRecentsInner(mTaskId, null);
19676        }
19677
19678        @Override
19679        public int startActivity(IBinder whoThread, String callingPackage,
19680                Intent intent, String resolvedType, Bundle options) {
19681            checkCaller();
19682
19683            int callingUser = UserHandle.getCallingUserId();
19684            TaskRecord tr;
19685            IApplicationThread appThread;
19686            synchronized (ActivityManagerService.this) {
19687                tr = recentTaskForIdLocked(mTaskId);
19688                if (tr == null) {
19689                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19690                }
19691                appThread = ApplicationThreadNative.asInterface(whoThread);
19692                if (appThread == null) {
19693                    throw new IllegalArgumentException("Bad app thread " + appThread);
19694                }
19695            }
19696            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19697                    resolvedType, null, null, null, null, 0, 0, null, null,
19698                    null, options, callingUser, null, tr);
19699        }
19700
19701        @Override
19702        public void setExcludeFromRecents(boolean exclude) {
19703            checkCaller();
19704
19705            synchronized (ActivityManagerService.this) {
19706                long origId = Binder.clearCallingIdentity();
19707                try {
19708                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19709                    if (tr == null) {
19710                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19711                    }
19712                    Intent intent = tr.getBaseIntent();
19713                    if (exclude) {
19714                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19715                    } else {
19716                        intent.setFlags(intent.getFlags()
19717                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19718                    }
19719                } finally {
19720                    Binder.restoreCallingIdentity(origId);
19721                }
19722            }
19723        }
19724    }
19725}
19726