ActivityManagerService.java revision bc0975b3afdb8ba80a6d54d898b299483ad680ad
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ITaskStackListener;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.SELinux;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.UpdateLock;
187import android.os.UserHandle;
188import android.os.UserManager;
189import android.provider.Settings;
190import android.text.format.DateUtils;
191import android.text.format.Time;
192import android.util.AtomicFile;
193import android.util.EventLog;
194import android.util.Log;
195import android.util.Pair;
196import android.util.PrintWriterPrinter;
197import android.util.Slog;
198import android.util.SparseArray;
199import android.util.TimeUtils;
200import android.util.Xml;
201import android.view.Gravity;
202import android.view.LayoutInflater;
203import android.view.View;
204import android.view.WindowManager;
205
206import dalvik.system.VMRuntime;
207
208import java.io.BufferedInputStream;
209import java.io.BufferedOutputStream;
210import java.io.DataInputStream;
211import java.io.DataOutputStream;
212import java.io.File;
213import java.io.FileDescriptor;
214import java.io.FileInputStream;
215import java.io.FileNotFoundException;
216import java.io.FileOutputStream;
217import java.io.IOException;
218import java.io.InputStreamReader;
219import java.io.PrintWriter;
220import java.io.StringWriter;
221import java.lang.ref.WeakReference;
222import java.util.ArrayList;
223import java.util.Arrays;
224import java.util.Collections;
225import java.util.Comparator;
226import java.util.HashMap;
227import java.util.HashSet;
228import java.util.Iterator;
229import java.util.List;
230import java.util.Locale;
231import java.util.Map;
232import java.util.Set;
233import java.util.concurrent.atomic.AtomicBoolean;
234import java.util.concurrent.atomic.AtomicLong;
235
236public final class ActivityManagerService extends ActivityManagerNative
237        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
238
239    private static final String USER_DATA_DIR = "/data/user/";
240    // File that stores last updated system version and called preboot receivers
241    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
242
243    static final String TAG = "ActivityManager";
244    static final String TAG_MU = "ActivityManagerServiceMU";
245    static final boolean DEBUG = false;
246    static final boolean localLOGV = DEBUG;
247    static final boolean DEBUG_BACKUP = localLOGV || false;
248    static final boolean DEBUG_BROADCAST = localLOGV || false;
249    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_CLEANUP = localLOGV || false;
252    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
253    static final boolean DEBUG_FOCUS = false;
254    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
255    static final boolean DEBUG_MU = localLOGV || false;
256    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
257    static final boolean DEBUG_LRU = localLOGV || false;
258    static final boolean DEBUG_PAUSE = localLOGV || false;
259    static final boolean DEBUG_POWER = localLOGV || false;
260    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
261    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
262    static final boolean DEBUG_PROCESSES = localLOGV || false;
263    static final boolean DEBUG_PROVIDER = localLOGV || false;
264    static final boolean DEBUG_RESULTS = localLOGV || false;
265    static final boolean DEBUG_SERVICE = localLOGV || false;
266    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
267    static final boolean DEBUG_STACK = localLOGV || false;
268    static final boolean DEBUG_SWITCH = localLOGV || false;
269    static final boolean DEBUG_TASKS = localLOGV || false;
270    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
271    static final boolean DEBUG_TRANSITION = localLOGV || false;
272    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
273    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
274    static final boolean DEBUG_VISBILITY = localLOGV || false;
275    static final boolean DEBUG_PSS = localLOGV || false;
276    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
277    static final boolean DEBUG_RECENTS = localLOGV || false;
278    static final boolean VALIDATE_TOKENS = false;
279    static final boolean SHOW_ACTIVITY_START_TIME = true;
280
281    // Control over CPU and battery monitoring.
282    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
283    static final boolean MONITOR_CPU_USAGE = true;
284    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
285    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
286    static final boolean MONITOR_THREAD_CPU_USAGE = false;
287
288    // The flags that are set for all calls we make to the package manager.
289    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
290
291    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
292
293    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
294
295    // Maximum number recent bitmaps to keep in memory.
296    static final int MAX_RECENT_BITMAPS = 3;
297
298    // Amount of time after a call to stopAppSwitches() during which we will
299    // prevent further untrusted switches from happening.
300    static final long APP_SWITCH_DELAY_TIME = 5*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real.
304    static final int PROC_START_TIMEOUT = 10*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real, when the process was
308    // started with a wrapper for instrumentation (such as Valgrind) because it
309    // could take much longer than usual.
310    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
311
312    // How long to wait after going idle before forcing apps to GC.
313    static final int GC_TIMEOUT = 5*1000;
314
315    // The minimum amount of time between successive GC requests for a process.
316    static final int GC_MIN_INTERVAL = 60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process.
319    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process
322    // when the request is due to the memory state being lowered.
323    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
324
325    // The rate at which we check for apps using excessive power -- 15 mins.
326    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on wake locks to start killing things.
330    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on CPU usage to start killing things.
334    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // How long we allow a receiver to run before giving up on it.
337    static final int BROADCAST_FG_TIMEOUT = 10*1000;
338    static final int BROADCAST_BG_TIMEOUT = 60*1000;
339
340    // How long we wait until we timeout on key dispatching.
341    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
342
343    // How long we wait until we timeout on key dispatching during instrumentation.
344    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
345
346    // Amount of time we wait for observers to handle a user switch before
347    // giving up on them and unfreezing the screen.
348    static final int USER_SWITCH_TIMEOUT = 2*1000;
349
350    // Maximum number of users we allow to be running at a time.
351    static final int MAX_RUNNING_USERS = 3;
352
353    // How long to wait in getAssistContextExtras for the activity and foreground services
354    // to respond with the result.
355    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
356
357    // Maximum number of persisted Uri grants a package is allowed
358    static final int MAX_PERSISTED_URI_GRANTS = 128;
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    // How many bytes to write into the dropbox log before truncating
365    static final int DROPBOX_MAX_SIZE = 256 * 1024;
366
367    // Access modes for handleIncomingUser.
368    static final int ALLOW_NON_FULL = 0;
369    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
370    static final int ALLOW_FULL_ONLY = 2;
371
372    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
373
374    // Delay in notifying task stack change listeners (in millis)
375    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
376
377    /** All system services */
378    SystemServiceManager mSystemServiceManager;
379
380    private Installer mInstaller;
381
382    /** Run all ActivityStacks through this */
383    ActivityStackSupervisor mStackSupervisor;
384
385    /** Task stack change listeners. */
386    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
387            new RemoteCallbackList<ITaskStackListener>();
388
389    public IntentFirewall mIntentFirewall;
390
391    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
392    // default actuion automatically.  Important for devices without direct input
393    // devices.
394    private boolean mShowDialogs = true;
395
396    BroadcastQueue mFgBroadcastQueue;
397    BroadcastQueue mBgBroadcastQueue;
398    // Convenient for easy iteration over the queues. Foreground is first
399    // so that dispatch of foreground broadcasts gets precedence.
400    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
401
402    BroadcastQueue broadcastQueueForIntent(Intent intent) {
403        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
404        if (DEBUG_BACKGROUND_BROADCAST) {
405            Slog.i(TAG, "Broadcast intent " + intent + " on "
406                    + (isFg ? "foreground" : "background")
407                    + " queue");
408        }
409        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
410    }
411
412    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
413        for (BroadcastQueue queue : mBroadcastQueues) {
414            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
415            if (r != null) {
416                return r;
417            }
418        }
419        return null;
420    }
421
422    /**
423     * Activity we have told the window manager to have key focus.
424     */
425    ActivityRecord mFocusedActivity = null;
426
427    /**
428     * List of intents that were used to start the most recent tasks.
429     */
430    ArrayList<TaskRecord> mRecentTasks;
431    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
432
433    /**
434     * For addAppTask: cached of the last activity component that was added.
435     */
436    ComponentName mLastAddedTaskComponent;
437
438    /**
439     * For addAppTask: cached of the last activity uid that was added.
440     */
441    int mLastAddedTaskUid;
442
443    /**
444     * For addAppTask: cached of the last ActivityInfo that was added.
445     */
446    ActivityInfo mLastAddedTaskActivity;
447
448    public class PendingAssistExtras extends Binder implements Runnable {
449        public final ActivityRecord activity;
450        public final Bundle extras;
451        public final Intent intent;
452        public final String hint;
453        public final int userHandle;
454        public boolean haveResult = false;
455        public Bundle result = null;
456        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
457                String _hint, int _userHandle) {
458            activity = _activity;
459            extras = _extras;
460            intent = _intent;
461            hint = _hint;
462            userHandle = _userHandle;
463        }
464        @Override
465        public void run() {
466            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
467            synchronized (this) {
468                haveResult = true;
469                notifyAll();
470            }
471        }
472    }
473
474    final ArrayList<PendingAssistExtras> mPendingAssistExtras
475            = new ArrayList<PendingAssistExtras>();
476
477    /**
478     * Process management.
479     */
480    final ProcessList mProcessList = new ProcessList();
481
482    /**
483     * All of the applications we currently have running organized by name.
484     * The keys are strings of the application package name (as
485     * returned by the package manager), and the keys are ApplicationRecord
486     * objects.
487     */
488    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
489
490    /**
491     * Tracking long-term execution of processes to look for abuse and other
492     * bad app behavior.
493     */
494    final ProcessStatsService mProcessStats;
495
496    /**
497     * The currently running isolated processes.
498     */
499    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
500
501    /**
502     * Counter for assigning isolated process uids, to avoid frequently reusing the
503     * same ones.
504     */
505    int mNextIsolatedProcessUid = 0;
506
507    /**
508     * The currently running heavy-weight process, if any.
509     */
510    ProcessRecord mHeavyWeightProcess = null;
511
512    /**
513     * The last time that various processes have crashed.
514     */
515    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
516
517    /**
518     * Information about a process that is currently marked as bad.
519     */
520    static final class BadProcessInfo {
521        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
522            this.time = time;
523            this.shortMsg = shortMsg;
524            this.longMsg = longMsg;
525            this.stack = stack;
526        }
527
528        final long time;
529        final String shortMsg;
530        final String longMsg;
531        final String stack;
532    }
533
534    /**
535     * Set of applications that we consider to be bad, and will reject
536     * incoming broadcasts from (which the user has no control over).
537     * Processes are added to this set when they have crashed twice within
538     * a minimum amount of time; they are removed from it when they are
539     * later restarted (hopefully due to some user action).  The value is the
540     * time it was added to the list.
541     */
542    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
543
544    /**
545     * All of the processes we currently have running organized by pid.
546     * The keys are the pid running the application.
547     *
548     * <p>NOTE: This object is protected by its own lock, NOT the global
549     * activity manager lock!
550     */
551    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
552
553    /**
554     * All of the processes that have been forced to be foreground.  The key
555     * is the pid of the caller who requested it (we hold a death
556     * link on it).
557     */
558    abstract class ForegroundToken implements IBinder.DeathRecipient {
559        int pid;
560        IBinder token;
561    }
562    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
563
564    /**
565     * List of records for processes that someone had tried to start before the
566     * system was ready.  We don't start them at that point, but ensure they
567     * are started by the time booting is complete.
568     */
569    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
570
571    /**
572     * List of persistent applications that are in the process
573     * of being started.
574     */
575    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * Processes that are being forcibly torn down.
579     */
580    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
581
582    /**
583     * List of running applications, sorted by recent usage.
584     * The first entry in the list is the least recently used.
585     */
586    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Where in mLruProcesses that the processes hosting activities start.
590     */
591    int mLruProcessActivityStart = 0;
592
593    /**
594     * Where in mLruProcesses that the processes hosting services start.
595     * This is after (lower index) than mLruProcessesActivityStart.
596     */
597    int mLruProcessServiceStart = 0;
598
599    /**
600     * List of processes that should gc as soon as things are idle.
601     */
602    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
603
604    /**
605     * Processes we want to collect PSS data from.
606     */
607    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
608
609    /**
610     * Last time we requested PSS data of all processes.
611     */
612    long mLastFullPssTime = SystemClock.uptimeMillis();
613
614    /**
615     * If set, the next time we collect PSS data we should do a full collection
616     * with data from native processes and the kernel.
617     */
618    boolean mFullPssPending = false;
619
620    /**
621     * This is the process holding what we currently consider to be
622     * the "home" activity.
623     */
624    ProcessRecord mHomeProcess;
625
626    /**
627     * This is the process holding the activity the user last visited that
628     * is in a different process from the one they are currently in.
629     */
630    ProcessRecord mPreviousProcess;
631
632    /**
633     * The time at which the previous process was last visible.
634     */
635    long mPreviousProcessVisibleTime;
636
637    /**
638     * Which uses have been started, so are allowed to run code.
639     */
640    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
641
642    /**
643     * LRU list of history of current users.  Most recently current is at the end.
644     */
645    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
646
647    /**
648     * Constant array of the users that are currently started.
649     */
650    int[] mStartedUserArray = new int[] { 0 };
651
652    /**
653     * Registered observers of the user switching mechanics.
654     */
655    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
656            = new RemoteCallbackList<IUserSwitchObserver>();
657
658    /**
659     * Currently active user switch.
660     */
661    Object mCurUserSwitchCallback;
662
663    /**
664     * Packages that the user has asked to have run in screen size
665     * compatibility mode instead of filling the screen.
666     */
667    final CompatModePackages mCompatModePackages;
668
669    /**
670     * Set of IntentSenderRecord objects that are currently active.
671     */
672    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
673            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
674
675    /**
676     * Fingerprints (hashCode()) of stack traces that we've
677     * already logged DropBox entries for.  Guarded by itself.  If
678     * something (rogue user app) forces this over
679     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
680     */
681    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
682    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
683
684    /**
685     * Strict Mode background batched logging state.
686     *
687     * The string buffer is guarded by itself, and its lock is also
688     * used to determine if another batched write is already
689     * in-flight.
690     */
691    private final StringBuilder mStrictModeBuffer = new StringBuilder();
692
693    /**
694     * Keeps track of all IIntentReceivers that have been registered for
695     * broadcasts.  Hash keys are the receiver IBinder, hash value is
696     * a ReceiverList.
697     */
698    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
699            new HashMap<IBinder, ReceiverList>();
700
701    /**
702     * Resolver for broadcast intents to registered receivers.
703     * Holds BroadcastFilter (subclass of IntentFilter).
704     */
705    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
706            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
707        @Override
708        protected boolean allowFilterResult(
709                BroadcastFilter filter, List<BroadcastFilter> dest) {
710            IBinder target = filter.receiverList.receiver.asBinder();
711            for (int i=dest.size()-1; i>=0; i--) {
712                if (dest.get(i).receiverList.receiver.asBinder() == target) {
713                    return false;
714                }
715            }
716            return true;
717        }
718
719        @Override
720        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
721            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
722                    || userId == filter.owningUserId) {
723                return super.newResult(filter, match, userId);
724            }
725            return null;
726        }
727
728        @Override
729        protected BroadcastFilter[] newArray(int size) {
730            return new BroadcastFilter[size];
731        }
732
733        @Override
734        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
735            return packageName.equals(filter.packageName);
736        }
737    };
738
739    /**
740     * State of all active sticky broadcasts per user.  Keys are the action of the
741     * sticky Intent, values are an ArrayList of all broadcasted intents with
742     * that action (which should usually be one).  The SparseArray is keyed
743     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
744     * for stickies that are sent to all users.
745     */
746    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
747            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
748
749    final ActiveServices mServices;
750
751    /**
752     * Backup/restore process management
753     */
754    String mBackupAppName = null;
755    BackupRecord mBackupTarget = null;
756
757    final ProviderMap mProviderMap;
758
759    /**
760     * List of content providers who have clients waiting for them.  The
761     * application is currently being launched and the provider will be
762     * removed from this list once it is published.
763     */
764    final ArrayList<ContentProviderRecord> mLaunchingProviders
765            = new ArrayList<ContentProviderRecord>();
766
767    /**
768     * File storing persisted {@link #mGrantedUriPermissions}.
769     */
770    private final AtomicFile mGrantFile;
771
772    /** XML constants used in {@link #mGrantFile} */
773    private static final String TAG_URI_GRANTS = "uri-grants";
774    private static final String TAG_URI_GRANT = "uri-grant";
775    private static final String ATTR_USER_HANDLE = "userHandle";
776    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
777    private static final String ATTR_TARGET_USER_ID = "targetUserId";
778    private static final String ATTR_SOURCE_PKG = "sourcePkg";
779    private static final String ATTR_TARGET_PKG = "targetPkg";
780    private static final String ATTR_URI = "uri";
781    private static final String ATTR_MODE_FLAGS = "modeFlags";
782    private static final String ATTR_CREATED_TIME = "createdTime";
783    private static final String ATTR_PREFIX = "prefix";
784
785    /**
786     * Global set of specific {@link Uri} permissions that have been granted.
787     * This optimized lookup structure maps from {@link UriPermission#targetUid}
788     * to {@link UriPermission#uri} to {@link UriPermission}.
789     */
790    @GuardedBy("this")
791    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
792            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
793
794    public static class GrantUri {
795        public final int sourceUserId;
796        public final Uri uri;
797        public boolean prefix;
798
799        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
800            this.sourceUserId = sourceUserId;
801            this.uri = uri;
802            this.prefix = prefix;
803        }
804
805        @Override
806        public int hashCode() {
807            int hashCode = 1;
808            hashCode = 31 * hashCode + sourceUserId;
809            hashCode = 31 * hashCode + uri.hashCode();
810            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
811            return hashCode;
812        }
813
814        @Override
815        public boolean equals(Object o) {
816            if (o instanceof GrantUri) {
817                GrantUri other = (GrantUri) o;
818                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
819                        && prefix == other.prefix;
820            }
821            return false;
822        }
823
824        @Override
825        public String toString() {
826            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
827            if (prefix) result += " [prefix]";
828            return result;
829        }
830
831        public String toSafeString() {
832            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
833            if (prefix) result += " [prefix]";
834            return result;
835        }
836
837        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
838            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
839                    ContentProvider.getUriWithoutUserId(uri), false);
840        }
841    }
842
843    CoreSettingsObserver mCoreSettingsObserver;
844
845    /**
846     * Thread-local storage used to carry caller permissions over through
847     * indirect content-provider access.
848     */
849    private class Identity {
850        public final IBinder token;
851        public final int pid;
852        public final int uid;
853
854        Identity(IBinder _token, int _pid, int _uid) {
855            token = _token;
856            pid = _pid;
857            uid = _uid;
858        }
859    }
860
861    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
862
863    /**
864     * All information we have collected about the runtime performance of
865     * any user id that can impact battery performance.
866     */
867    final BatteryStatsService mBatteryStatsService;
868
869    /**
870     * Information about component usage
871     */
872    UsageStatsManagerInternal mUsageStatsService;
873
874    /**
875     * Information about and control over application operations
876     */
877    final AppOpsService mAppOpsService;
878
879    /**
880     * Save recent tasks information across reboots.
881     */
882    final TaskPersister mTaskPersister;
883
884    /**
885     * Current configuration information.  HistoryRecord objects are given
886     * a reference to this object to indicate which configuration they are
887     * currently running in, so this object must be kept immutable.
888     */
889    Configuration mConfiguration = new Configuration();
890
891    /**
892     * Current sequencing integer of the configuration, for skipping old
893     * configurations.
894     */
895    int mConfigurationSeq = 0;
896
897    /**
898     * Hardware-reported OpenGLES version.
899     */
900    final int GL_ES_VERSION;
901
902    /**
903     * List of initialization arguments to pass to all processes when binding applications to them.
904     * For example, references to the commonly used services.
905     */
906    HashMap<String, IBinder> mAppBindArgs;
907
908    /**
909     * Temporary to avoid allocations.  Protected by main lock.
910     */
911    final StringBuilder mStringBuilder = new StringBuilder(256);
912
913    /**
914     * Used to control how we initialize the service.
915     */
916    ComponentName mTopComponent;
917    String mTopAction = Intent.ACTION_MAIN;
918    String mTopData;
919    boolean mProcessesReady = false;
920    boolean mSystemReady = false;
921    boolean mBooting = false;
922    boolean mCallFinishBooting = false;
923    boolean mBootAnimationComplete = false;
924    boolean mWaitingUpdate = false;
925    boolean mDidUpdate = false;
926    boolean mOnBattery = false;
927    boolean mLaunchWarningShown = false;
928
929    Context mContext;
930
931    int mFactoryTest;
932
933    boolean mCheckedForSetup;
934
935    /**
936     * The time at which we will allow normal application switches again,
937     * after a call to {@link #stopAppSwitches()}.
938     */
939    long mAppSwitchesAllowedTime;
940
941    /**
942     * This is set to true after the first switch after mAppSwitchesAllowedTime
943     * is set; any switches after that will clear the time.
944     */
945    boolean mDidAppSwitch;
946
947    /**
948     * Last time (in realtime) at which we checked for power usage.
949     */
950    long mLastPowerCheckRealtime;
951
952    /**
953     * Last time (in uptime) at which we checked for power usage.
954     */
955    long mLastPowerCheckUptime;
956
957    /**
958     * Set while we are wanting to sleep, to prevent any
959     * activities from being started/resumed.
960     */
961    private boolean mSleeping = false;
962
963    /**
964     * Set while we are running a voice interaction.  This overrides
965     * sleeping while it is active.
966     */
967    private boolean mRunningVoice = false;
968
969    /**
970     * State of external calls telling us if the device is awake or asleep.
971     */
972    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
973
974    static final int LOCK_SCREEN_HIDDEN = 0;
975    static final int LOCK_SCREEN_LEAVING = 1;
976    static final int LOCK_SCREEN_SHOWN = 2;
977    /**
978     * State of external call telling us if the lock screen is shown.
979     */
980    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
981
982    /**
983     * Set if we are shutting down the system, similar to sleeping.
984     */
985    boolean mShuttingDown = false;
986
987    /**
988     * Current sequence id for oom_adj computation traversal.
989     */
990    int mAdjSeq = 0;
991
992    /**
993     * Current sequence id for process LRU updating.
994     */
995    int mLruSeq = 0;
996
997    /**
998     * Keep track of the non-cached/empty process we last found, to help
999     * determine how to distribute cached/empty processes next time.
1000     */
1001    int mNumNonCachedProcs = 0;
1002
1003    /**
1004     * Keep track of the number of cached hidden procs, to balance oom adj
1005     * distribution between those and empty procs.
1006     */
1007    int mNumCachedHiddenProcs = 0;
1008
1009    /**
1010     * Keep track of the number of service processes we last found, to
1011     * determine on the next iteration which should be B services.
1012     */
1013    int mNumServiceProcs = 0;
1014    int mNewNumAServiceProcs = 0;
1015    int mNewNumServiceProcs = 0;
1016
1017    /**
1018     * Allow the current computed overall memory level of the system to go down?
1019     * This is set to false when we are killing processes for reasons other than
1020     * memory management, so that the now smaller process list will not be taken as
1021     * an indication that memory is tighter.
1022     */
1023    boolean mAllowLowerMemLevel = false;
1024
1025    /**
1026     * The last computed memory level, for holding when we are in a state that
1027     * processes are going away for other reasons.
1028     */
1029    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1030
1031    /**
1032     * The last total number of process we have, to determine if changes actually look
1033     * like a shrinking number of process due to lower RAM.
1034     */
1035    int mLastNumProcesses;
1036
1037    /**
1038     * The uptime of the last time we performed idle maintenance.
1039     */
1040    long mLastIdleTime = SystemClock.uptimeMillis();
1041
1042    /**
1043     * Total time spent with RAM that has been added in the past since the last idle time.
1044     */
1045    long mLowRamTimeSinceLastIdle = 0;
1046
1047    /**
1048     * If RAM is currently low, when that horrible situation started.
1049     */
1050    long mLowRamStartTime = 0;
1051
1052    /**
1053     * For reporting to battery stats the current top application.
1054     */
1055    private String mCurResumedPackage = null;
1056    private int mCurResumedUid = -1;
1057
1058    /**
1059     * For reporting to battery stats the apps currently running foreground
1060     * service.  The ProcessMap is package/uid tuples; each of these contain
1061     * an array of the currently foreground processes.
1062     */
1063    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1064            = new ProcessMap<ArrayList<ProcessRecord>>();
1065
1066    /**
1067     * This is set if we had to do a delayed dexopt of an app before launching
1068     * it, to increase the ANR timeouts in that case.
1069     */
1070    boolean mDidDexOpt;
1071
1072    /**
1073     * Set if the systemServer made a call to enterSafeMode.
1074     */
1075    boolean mSafeMode;
1076
1077    String mDebugApp = null;
1078    boolean mWaitForDebugger = false;
1079    boolean mDebugTransient = false;
1080    String mOrigDebugApp = null;
1081    boolean mOrigWaitForDebugger = false;
1082    boolean mAlwaysFinishActivities = false;
1083    IActivityController mController = null;
1084    String mProfileApp = null;
1085    ProcessRecord mProfileProc = null;
1086    String mProfileFile;
1087    ParcelFileDescriptor mProfileFd;
1088    int mSamplingInterval = 0;
1089    boolean mAutoStopProfiler = false;
1090    int mProfileType = 0;
1091    String mOpenGlTraceApp = null;
1092
1093    static class ProcessChangeItem {
1094        static final int CHANGE_ACTIVITIES = 1<<0;
1095        static final int CHANGE_PROCESS_STATE = 1<<1;
1096        int changes;
1097        int uid;
1098        int pid;
1099        int processState;
1100        boolean foregroundActivities;
1101    }
1102
1103    final RemoteCallbackList<IProcessObserver> mProcessObservers
1104            = new RemoteCallbackList<IProcessObserver>();
1105    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1106
1107    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1108            = new ArrayList<ProcessChangeItem>();
1109    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1110            = new ArrayList<ProcessChangeItem>();
1111
1112    /**
1113     * Runtime CPU use collection thread.  This object's lock is used to
1114     * perform synchronization with the thread (notifying it to run).
1115     */
1116    final Thread mProcessCpuThread;
1117
1118    /**
1119     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1120     * Must acquire this object's lock when accessing it.
1121     * NOTE: this lock will be held while doing long operations (trawling
1122     * through all processes in /proc), so it should never be acquired by
1123     * any critical paths such as when holding the main activity manager lock.
1124     */
1125    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1126            MONITOR_THREAD_CPU_USAGE);
1127    final AtomicLong mLastCpuTime = new AtomicLong(0);
1128    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1129
1130    long mLastWriteTime = 0;
1131
1132    /**
1133     * Used to retain an update lock when the foreground activity is in
1134     * immersive mode.
1135     */
1136    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1137
1138    /**
1139     * Set to true after the system has finished booting.
1140     */
1141    boolean mBooted = false;
1142
1143    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1144    int mProcessLimitOverride = -1;
1145
1146    WindowManagerService mWindowManager;
1147
1148    final ActivityThread mSystemThread;
1149
1150    // Holds the current foreground user's id
1151    int mCurrentUserId = 0;
1152    // Holds the target user's id during a user switch
1153    int mTargetUserId = UserHandle.USER_NULL;
1154    // If there are multiple profiles for the current user, their ids are here
1155    // Currently only the primary user can have managed profiles
1156    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1157
1158    /**
1159     * Mapping from each known user ID to the profile group ID it is associated with.
1160     */
1161    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1162
1163    private UserManagerService mUserManager;
1164
1165    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1166        final ProcessRecord mApp;
1167        final int mPid;
1168        final IApplicationThread mAppThread;
1169
1170        AppDeathRecipient(ProcessRecord app, int pid,
1171                IApplicationThread thread) {
1172            if (localLOGV) Slog.v(
1173                TAG, "New death recipient " + this
1174                + " for thread " + thread.asBinder());
1175            mApp = app;
1176            mPid = pid;
1177            mAppThread = thread;
1178        }
1179
1180        @Override
1181        public void binderDied() {
1182            if (localLOGV) Slog.v(
1183                TAG, "Death received in " + this
1184                + " for thread " + mAppThread.asBinder());
1185            synchronized(ActivityManagerService.this) {
1186                appDiedLocked(mApp, mPid, mAppThread);
1187            }
1188        }
1189    }
1190
1191    static final int SHOW_ERROR_MSG = 1;
1192    static final int SHOW_NOT_RESPONDING_MSG = 2;
1193    static final int SHOW_FACTORY_ERROR_MSG = 3;
1194    static final int UPDATE_CONFIGURATION_MSG = 4;
1195    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1196    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1197    static final int SERVICE_TIMEOUT_MSG = 12;
1198    static final int UPDATE_TIME_ZONE = 13;
1199    static final int SHOW_UID_ERROR_MSG = 14;
1200    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1201    static final int PROC_START_TIMEOUT_MSG = 20;
1202    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1203    static final int KILL_APPLICATION_MSG = 22;
1204    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1205    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1206    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1207    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1208    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1209    static final int CLEAR_DNS_CACHE_MSG = 28;
1210    static final int UPDATE_HTTP_PROXY_MSG = 29;
1211    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1212    static final int DISPATCH_PROCESSES_CHANGED = 31;
1213    static final int DISPATCH_PROCESS_DIED = 32;
1214    static final int REPORT_MEM_USAGE_MSG = 33;
1215    static final int REPORT_USER_SWITCH_MSG = 34;
1216    static final int CONTINUE_USER_SWITCH_MSG = 35;
1217    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1218    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1219    static final int PERSIST_URI_GRANTS_MSG = 38;
1220    static final int REQUEST_ALL_PSS_MSG = 39;
1221    static final int START_PROFILES_MSG = 40;
1222    static final int UPDATE_TIME = 41;
1223    static final int SYSTEM_USER_START_MSG = 42;
1224    static final int SYSTEM_USER_CURRENT_MSG = 43;
1225    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1226    static final int FINISH_BOOTING_MSG = 45;
1227    static final int START_USER_SWITCH_MSG = 46;
1228    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1229    static final int DISMISS_DIALOG_MSG = 48;
1230    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1231
1232    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1233    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1234    static final int FIRST_COMPAT_MODE_MSG = 300;
1235    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1236
1237    CompatModeDialog mCompatModeDialog;
1238    long mLastMemUsageReportTime = 0;
1239
1240    /**
1241     * Flag whether the current user is a "monkey", i.e. whether
1242     * the UI is driven by a UI automation tool.
1243     */
1244    private boolean mUserIsMonkey;
1245
1246    /** Flag whether the device has a Recents UI */
1247    boolean mHasRecents;
1248
1249    /** The dimensions of the thumbnails in the Recents UI. */
1250    int mThumbnailWidth;
1251    int mThumbnailHeight;
1252
1253    final ServiceThread mHandlerThread;
1254    final MainHandler mHandler;
1255
1256    final class MainHandler extends Handler {
1257        public MainHandler(Looper looper) {
1258            super(looper, null, true);
1259        }
1260
1261        @Override
1262        public void handleMessage(Message msg) {
1263            switch (msg.what) {
1264            case SHOW_ERROR_MSG: {
1265                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1266                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1267                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord)data.get("app");
1270                    AppErrorResult res = (AppErrorResult) data.get("result");
1271                    if (proc != null && proc.crashDialog != null) {
1272                        Slog.e(TAG, "App already has crash dialog: " + proc);
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                        return;
1277                    }
1278                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1279                            >= Process.FIRST_APPLICATION_UID
1280                            && proc.pid != MY_PID);
1281                    for (int userId : mCurrentProfileIds) {
1282                        isBackground &= (proc.userId != userId);
1283                    }
1284                    if (isBackground && !showBackground) {
1285                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1286                        if (res != null) {
1287                            res.set(0);
1288                        }
1289                        return;
1290                    }
1291                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1292                        Dialog d = new AppErrorDialog(mContext,
1293                                ActivityManagerService.this, res, proc);
1294                        d.show();
1295                        proc.crashDialog = d;
1296                    } else {
1297                        // The device is asleep, so just pretend that the user
1298                        // saw a crash dialog and hit "force quit".
1299                        if (res != null) {
1300                            res.set(0);
1301                        }
1302                    }
1303                }
1304
1305                ensureBootCompleted();
1306            } break;
1307            case SHOW_NOT_RESPONDING_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1310                    ProcessRecord proc = (ProcessRecord)data.get("app");
1311                    if (proc != null && proc.anrDialog != null) {
1312                        Slog.e(TAG, "App already has anr dialog: " + proc);
1313                        return;
1314                    }
1315
1316                    Intent intent = new Intent("android.intent.action.ANR");
1317                    if (!mProcessesReady) {
1318                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1319                                | Intent.FLAG_RECEIVER_FOREGROUND);
1320                    }
1321                    broadcastIntentLocked(null, null, intent,
1322                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1323                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1324
1325                    if (mShowDialogs) {
1326                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1327                                mContext, proc, (ActivityRecord)data.get("activity"),
1328                                msg.arg1 != 0);
1329                        d.show();
1330                        proc.anrDialog = d;
1331                    } else {
1332                        // Just kill the app if there is no dialog to be shown.
1333                        killAppAtUsersRequest(proc, null);
1334                    }
1335                }
1336
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1340                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord proc = (ProcessRecord) data.get("app");
1343                    if (proc == null) {
1344                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1345                        break;
1346                    }
1347                    if (proc.crashDialog != null) {
1348                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1349                        return;
1350                    }
1351                    AppErrorResult res = (AppErrorResult) data.get("result");
1352                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1353                        Dialog d = new StrictModeViolationDialog(mContext,
1354                                ActivityManagerService.this, res, proc);
1355                        d.show();
1356                        proc.crashDialog = d;
1357                    } else {
1358                        // The device is asleep, so just pretend that the user
1359                        // saw a crash dialog and hit "force quit".
1360                        res.set(0);
1361                    }
1362                }
1363                ensureBootCompleted();
1364            } break;
1365            case SHOW_FACTORY_ERROR_MSG: {
1366                Dialog d = new FactoryErrorDialog(
1367                    mContext, msg.getData().getCharSequence("msg"));
1368                d.show();
1369                ensureBootCompleted();
1370            } break;
1371            case UPDATE_CONFIGURATION_MSG: {
1372                final ContentResolver resolver = mContext.getContentResolver();
1373                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1374            } break;
1375            case GC_BACKGROUND_PROCESSES_MSG: {
1376                synchronized (ActivityManagerService.this) {
1377                    performAppGcsIfAppropriateLocked();
1378                }
1379            } break;
1380            case WAIT_FOR_DEBUGGER_MSG: {
1381                synchronized (ActivityManagerService.this) {
1382                    ProcessRecord app = (ProcessRecord)msg.obj;
1383                    if (msg.arg1 != 0) {
1384                        if (!app.waitedForDebugger) {
1385                            Dialog d = new AppWaitingForDebuggerDialog(
1386                                    ActivityManagerService.this,
1387                                    mContext, app);
1388                            app.waitDialog = d;
1389                            app.waitedForDebugger = true;
1390                            d.show();
1391                        }
1392                    } else {
1393                        if (app.waitDialog != null) {
1394                            app.waitDialog.dismiss();
1395                            app.waitDialog = null;
1396                        }
1397                    }
1398                }
1399            } break;
1400            case SERVICE_TIMEOUT_MSG: {
1401                if (mDidDexOpt) {
1402                    mDidDexOpt = false;
1403                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1404                    nmsg.obj = msg.obj;
1405                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1406                    return;
1407                }
1408                mServices.serviceTimeout((ProcessRecord)msg.obj);
1409            } break;
1410            case UPDATE_TIME_ZONE: {
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.updateTimeZone();
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case CLEAR_DNS_CACHE_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1427                        ProcessRecord r = mLruProcesses.get(i);
1428                        if (r.thread != null) {
1429                            try {
1430                                r.thread.clearDnsCache();
1431                            } catch (RemoteException ex) {
1432                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case UPDATE_HTTP_PROXY_MSG: {
1439                ProxyInfo proxy = (ProxyInfo)msg.obj;
1440                String host = "";
1441                String port = "";
1442                String exclList = "";
1443                Uri pacFileUrl = Uri.EMPTY;
1444                if (proxy != null) {
1445                    host = proxy.getHost();
1446                    port = Integer.toString(proxy.getPort());
1447                    exclList = proxy.getExclusionListAsString();
1448                    pacFileUrl = proxy.getPacFileUrl();
1449                }
1450                synchronized (ActivityManagerService.this) {
1451                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1452                        ProcessRecord r = mLruProcesses.get(i);
1453                        if (r.thread != null) {
1454                            try {
1455                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1456                            } catch (RemoteException ex) {
1457                                Slog.w(TAG, "Failed to update http proxy for: " +
1458                                        r.info.processName);
1459                            }
1460                        }
1461                    }
1462                }
1463            } break;
1464            case SHOW_UID_ERROR_MSG: {
1465                if (mShowDialogs) {
1466                    AlertDialog d = new BaseErrorDialog(mContext);
1467                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1468                    d.setCancelable(false);
1469                    d.setTitle(mContext.getText(R.string.android_system_label));
1470                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1471                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1472                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1473                    d.show();
1474                }
1475            } break;
1476            case SHOW_FINGERPRINT_ERROR_MSG: {
1477                if (mShowDialogs) {
1478                    AlertDialog d = new BaseErrorDialog(mContext);
1479                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1480                    d.setCancelable(false);
1481                    d.setTitle(mContext.getText(R.string.android_system_label));
1482                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1483                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1484                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1485                    d.show();
1486                }
1487            } break;
1488            case PROC_START_TIMEOUT_MSG: {
1489                if (mDidDexOpt) {
1490                    mDidDexOpt = false;
1491                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1492                    nmsg.obj = msg.obj;
1493                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1494                    return;
1495                }
1496                ProcessRecord app = (ProcessRecord)msg.obj;
1497                synchronized (ActivityManagerService.this) {
1498                    processStartTimedOutLocked(app);
1499                }
1500            } break;
1501            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1504                }
1505            } break;
1506            case KILL_APPLICATION_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    int appid = msg.arg1;
1509                    boolean restart = (msg.arg2 == 1);
1510                    Bundle bundle = (Bundle)msg.obj;
1511                    String pkg = bundle.getString("pkg");
1512                    String reason = bundle.getString("reason");
1513                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1514                            false, UserHandle.USER_ALL, reason);
1515                }
1516            } break;
1517            case FINALIZE_PENDING_INTENT_MSG: {
1518                ((PendingIntentRecord)msg.obj).completeFinalize();
1519            } break;
1520            case POST_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525
1526                ActivityRecord root = (ActivityRecord)msg.obj;
1527                ProcessRecord process = root.app;
1528                if (process == null) {
1529                    return;
1530                }
1531
1532                try {
1533                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1534                    String text = mContext.getString(R.string.heavy_weight_notification,
1535                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1536                    Notification notification = new Notification();
1537                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1538                    notification.when = 0;
1539                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1540                    notification.tickerText = text;
1541                    notification.defaults = 0; // please be quiet
1542                    notification.sound = null;
1543                    notification.vibrate = null;
1544                    notification.color = mContext.getResources().getColor(
1545                            com.android.internal.R.color.system_notification_accent_color);
1546                    notification.setLatestEventInfo(context, text,
1547                            mContext.getText(R.string.heavy_weight_notification_detail),
1548                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1549                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1550                                    new UserHandle(root.userId)));
1551
1552                    try {
1553                        int[] outId = new int[1];
1554                        inm.enqueueNotificationWithTag("android", "android", null,
1555                                R.string.heavy_weight_notification,
1556                                notification, outId, root.userId);
1557                    } catch (RuntimeException e) {
1558                        Slog.w(ActivityManagerService.TAG,
1559                                "Error showing notification for heavy-weight app", e);
1560                    } catch (RemoteException e) {
1561                    }
1562                } catch (NameNotFoundException e) {
1563                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1564                }
1565            } break;
1566            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1567                INotificationManager inm = NotificationManager.getService();
1568                if (inm == null) {
1569                    return;
1570                }
1571                try {
1572                    inm.cancelNotificationWithTag("android", null,
1573                            R.string.heavy_weight_notification,  msg.arg1);
1574                } catch (RuntimeException e) {
1575                    Slog.w(ActivityManagerService.TAG,
1576                            "Error canceling notification for service", e);
1577                } catch (RemoteException e) {
1578                }
1579            } break;
1580            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1581                synchronized (ActivityManagerService.this) {
1582                    checkExcessivePowerUsageLocked(true);
1583                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1584                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1585                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1586                }
1587            } break;
1588            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1589                synchronized (ActivityManagerService.this) {
1590                    ActivityRecord ar = (ActivityRecord)msg.obj;
1591                    if (mCompatModeDialog != null) {
1592                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1593                                ar.info.applicationInfo.packageName)) {
1594                            return;
1595                        }
1596                        mCompatModeDialog.dismiss();
1597                        mCompatModeDialog = null;
1598                    }
1599                    if (ar != null && false) {
1600                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1601                                ar.packageName)) {
1602                            int mode = mCompatModePackages.computeCompatModeLocked(
1603                                    ar.info.applicationInfo);
1604                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1605                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1606                                mCompatModeDialog = new CompatModeDialog(
1607                                        ActivityManagerService.this, mContext,
1608                                        ar.info.applicationInfo);
1609                                mCompatModeDialog.show();
1610                            }
1611                        }
1612                    }
1613                }
1614                break;
1615            }
1616            case DISPATCH_PROCESSES_CHANGED: {
1617                dispatchProcessesChanged();
1618                break;
1619            }
1620            case DISPATCH_PROCESS_DIED: {
1621                final int pid = msg.arg1;
1622                final int uid = msg.arg2;
1623                dispatchProcessDied(pid, uid);
1624                break;
1625            }
1626            case REPORT_MEM_USAGE_MSG: {
1627                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1628                Thread thread = new Thread() {
1629                    @Override public void run() {
1630                        reportMemUsage(memInfos);
1631                    }
1632                };
1633                thread.start();
1634                break;
1635            }
1636            case START_USER_SWITCH_MSG: {
1637                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1638                break;
1639            }
1640            case REPORT_USER_SWITCH_MSG: {
1641                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1642                break;
1643            }
1644            case CONTINUE_USER_SWITCH_MSG: {
1645                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1646                break;
1647            }
1648            case USER_SWITCH_TIMEOUT_MSG: {
1649                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1650                break;
1651            }
1652            case IMMERSIVE_MODE_LOCK_MSG: {
1653                final boolean nextState = (msg.arg1 != 0);
1654                if (mUpdateLock.isHeld() != nextState) {
1655                    if (DEBUG_IMMERSIVE) {
1656                        final ActivityRecord r = (ActivityRecord) msg.obj;
1657                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1658                    }
1659                    if (nextState) {
1660                        mUpdateLock.acquire();
1661                    } else {
1662                        mUpdateLock.release();
1663                    }
1664                }
1665                break;
1666            }
1667            case PERSIST_URI_GRANTS_MSG: {
1668                writeGrantedUriPermissions();
1669                break;
1670            }
1671            case REQUEST_ALL_PSS_MSG: {
1672                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1673                break;
1674            }
1675            case START_PROFILES_MSG: {
1676                synchronized (ActivityManagerService.this) {
1677                    startProfilesLocked();
1678                }
1679                break;
1680            }
1681            case UPDATE_TIME: {
1682                synchronized (ActivityManagerService.this) {
1683                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1684                        ProcessRecord r = mLruProcesses.get(i);
1685                        if (r.thread != null) {
1686                            try {
1687                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1688                            } catch (RemoteException ex) {
1689                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case SYSTEM_USER_START_MSG: {
1697                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1698                        Integer.toString(msg.arg1), msg.arg1);
1699                mSystemServiceManager.startUser(msg.arg1);
1700                break;
1701            }
1702            case SYSTEM_USER_CURRENT_MSG: {
1703                mBatteryStatsService.noteEvent(
1704                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1705                        Integer.toString(msg.arg2), msg.arg2);
1706                mBatteryStatsService.noteEvent(
1707                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1708                        Integer.toString(msg.arg1), msg.arg1);
1709                mSystemServiceManager.switchUser(msg.arg1);
1710                break;
1711            }
1712            case ENTER_ANIMATION_COMPLETE_MSG: {
1713                synchronized (ActivityManagerService.this) {
1714                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1715                    if (r != null && r.app != null && r.app.thread != null) {
1716                        try {
1717                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1718                        } catch (RemoteException e) {
1719                        }
1720                    }
1721                }
1722                break;
1723            }
1724            case FINISH_BOOTING_MSG: {
1725                if (msg.arg1 != 0) {
1726                    finishBooting();
1727                }
1728                if (msg.arg2 != 0) {
1729                    enableScreenAfterBoot();
1730                }
1731                break;
1732            }
1733            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1734                try {
1735                    Locale l = (Locale) msg.obj;
1736                    IBinder service = ServiceManager.getService("mount");
1737                    IMountService mountService = IMountService.Stub.asInterface(service);
1738                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1739                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1740                } catch (RemoteException e) {
1741                    Log.e(TAG, "Error storing locale for decryption UI", e);
1742                }
1743                break;
1744            }
1745            case DISMISS_DIALOG_MSG: {
1746                final Dialog d = (Dialog) msg.obj;
1747                d.dismiss();
1748                break;
1749            }
1750            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1751                synchronized (ActivityManagerService.this) {
1752                    int i = mTaskStackListeners.beginBroadcast();
1753                    while (i > 0) {
1754                        i--;
1755                        try {
1756                            // Make a one-way callback to the listener
1757                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1758                        } catch (RemoteException e){
1759                            // Handled by the RemoteCallbackList
1760                        }
1761                    }
1762                    mTaskStackListeners.finishBroadcast();
1763                }
1764                break;
1765            }
1766            }
1767        }
1768    };
1769
1770    static final int COLLECT_PSS_BG_MSG = 1;
1771
1772    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1773        @Override
1774        public void handleMessage(Message msg) {
1775            switch (msg.what) {
1776            case COLLECT_PSS_BG_MSG: {
1777                long start = SystemClock.uptimeMillis();
1778                MemInfoReader memInfo = null;
1779                synchronized (ActivityManagerService.this) {
1780                    if (mFullPssPending) {
1781                        mFullPssPending = false;
1782                        memInfo = new MemInfoReader();
1783                    }
1784                }
1785                if (memInfo != null) {
1786                    updateCpuStatsNow();
1787                    long nativeTotalPss = 0;
1788                    synchronized (mProcessCpuTracker) {
1789                        final int N = mProcessCpuTracker.countStats();
1790                        for (int j=0; j<N; j++) {
1791                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1792                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1793                                // This is definitely an application process; skip it.
1794                                continue;
1795                            }
1796                            synchronized (mPidsSelfLocked) {
1797                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1798                                    // This is one of our own processes; skip it.
1799                                    continue;
1800                                }
1801                            }
1802                            nativeTotalPss += Debug.getPss(st.pid, null);
1803                        }
1804                    }
1805                    memInfo.readMemInfo();
1806                    synchronized (ActivityManagerService.this) {
1807                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1808                                + (SystemClock.uptimeMillis()-start) + "ms");
1809                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1810                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1811                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1812                    }
1813                }
1814
1815                int i = 0;
1816                int num = 0;
1817                long[] tmp = new long[1];
1818                do {
1819                    ProcessRecord proc;
1820                    int procState;
1821                    int pid;
1822                    synchronized (ActivityManagerService.this) {
1823                        if (i >= mPendingPssProcesses.size()) {
1824                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1825                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1826                            mPendingPssProcesses.clear();
1827                            return;
1828                        }
1829                        proc = mPendingPssProcesses.get(i);
1830                        procState = proc.pssProcState;
1831                        if (proc.thread != null && procState == proc.setProcState) {
1832                            pid = proc.pid;
1833                        } else {
1834                            proc = null;
1835                            pid = 0;
1836                        }
1837                        i++;
1838                    }
1839                    if (proc != null) {
1840                        long pss = Debug.getPss(pid, tmp);
1841                        synchronized (ActivityManagerService.this) {
1842                            if (proc.thread != null && proc.setProcState == procState
1843                                    && proc.pid == pid) {
1844                                num++;
1845                                proc.lastPssTime = SystemClock.uptimeMillis();
1846                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1847                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1848                                        + ": " + pss + " lastPss=" + proc.lastPss
1849                                        + " state=" + ProcessList.makeProcStateString(procState));
1850                                if (proc.initialIdlePss == 0) {
1851                                    proc.initialIdlePss = pss;
1852                                }
1853                                proc.lastPss = pss;
1854                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1855                                    proc.lastCachedPss = pss;
1856                                }
1857                            }
1858                        }
1859                    }
1860                } while (true);
1861            }
1862            }
1863        }
1864    };
1865
1866    public void setSystemProcess() {
1867        try {
1868            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1869            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1870            ServiceManager.addService("meminfo", new MemBinder(this));
1871            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1872            ServiceManager.addService("dbinfo", new DbBinder(this));
1873            if (MONITOR_CPU_USAGE) {
1874                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1875            }
1876            ServiceManager.addService("permission", new PermissionController(this));
1877
1878            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1879                    "android", STOCK_PM_FLAGS);
1880            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1881
1882            synchronized (this) {
1883                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1884                app.persistent = true;
1885                app.pid = MY_PID;
1886                app.maxAdj = ProcessList.SYSTEM_ADJ;
1887                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1888                mProcessNames.put(app.processName, app.uid, app);
1889                synchronized (mPidsSelfLocked) {
1890                    mPidsSelfLocked.put(app.pid, app);
1891                }
1892                updateLruProcessLocked(app, false, null);
1893                updateOomAdjLocked();
1894            }
1895        } catch (PackageManager.NameNotFoundException e) {
1896            throw new RuntimeException(
1897                    "Unable to find android system package", e);
1898        }
1899    }
1900
1901    public void setWindowManager(WindowManagerService wm) {
1902        mWindowManager = wm;
1903        mStackSupervisor.setWindowManager(wm);
1904    }
1905
1906    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1907        mUsageStatsService = usageStatsManager;
1908    }
1909
1910    public void startObservingNativeCrashes() {
1911        final NativeCrashListener ncl = new NativeCrashListener(this);
1912        ncl.start();
1913    }
1914
1915    public IAppOpsService getAppOpsService() {
1916        return mAppOpsService;
1917    }
1918
1919    static class MemBinder extends Binder {
1920        ActivityManagerService mActivityManagerService;
1921        MemBinder(ActivityManagerService activityManagerService) {
1922            mActivityManagerService = activityManagerService;
1923        }
1924
1925        @Override
1926        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1927            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1928                    != PackageManager.PERMISSION_GRANTED) {
1929                pw.println("Permission Denial: can't dump meminfo from from pid="
1930                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1931                        + " without permission " + android.Manifest.permission.DUMP);
1932                return;
1933            }
1934
1935            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1936        }
1937    }
1938
1939    static class GraphicsBinder extends Binder {
1940        ActivityManagerService mActivityManagerService;
1941        GraphicsBinder(ActivityManagerService activityManagerService) {
1942            mActivityManagerService = activityManagerService;
1943        }
1944
1945        @Override
1946        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1947            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1948                    != PackageManager.PERMISSION_GRANTED) {
1949                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1950                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1951                        + " without permission " + android.Manifest.permission.DUMP);
1952                return;
1953            }
1954
1955            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1956        }
1957    }
1958
1959    static class DbBinder extends Binder {
1960        ActivityManagerService mActivityManagerService;
1961        DbBinder(ActivityManagerService activityManagerService) {
1962            mActivityManagerService = activityManagerService;
1963        }
1964
1965        @Override
1966        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1967            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1968                    != PackageManager.PERMISSION_GRANTED) {
1969                pw.println("Permission Denial: can't dump dbinfo from from pid="
1970                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1971                        + " without permission " + android.Manifest.permission.DUMP);
1972                return;
1973            }
1974
1975            mActivityManagerService.dumpDbInfo(fd, pw, args);
1976        }
1977    }
1978
1979    static class CpuBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        CpuBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            synchronized (mActivityManagerService.mProcessCpuTracker) {
1996                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1997                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1998                        SystemClock.uptimeMillis()));
1999            }
2000        }
2001    }
2002
2003    public static final class Lifecycle extends SystemService {
2004        private final ActivityManagerService mService;
2005
2006        public Lifecycle(Context context) {
2007            super(context);
2008            mService = new ActivityManagerService(context);
2009        }
2010
2011        @Override
2012        public void onStart() {
2013            mService.start();
2014        }
2015
2016        public ActivityManagerService getService() {
2017            return mService;
2018        }
2019    }
2020
2021    // Note: This method is invoked on the main thread but may need to attach various
2022    // handlers to other threads.  So take care to be explicit about the looper.
2023    public ActivityManagerService(Context systemContext) {
2024        mContext = systemContext;
2025        mFactoryTest = FactoryTest.getMode();
2026        mSystemThread = ActivityThread.currentActivityThread();
2027
2028        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2029
2030        mHandlerThread = new ServiceThread(TAG,
2031                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2032        mHandlerThread.start();
2033        mHandler = new MainHandler(mHandlerThread.getLooper());
2034
2035        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2036                "foreground", BROADCAST_FG_TIMEOUT, false);
2037        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "background", BROADCAST_BG_TIMEOUT, true);
2039        mBroadcastQueues[0] = mFgBroadcastQueue;
2040        mBroadcastQueues[1] = mBgBroadcastQueue;
2041
2042        mServices = new ActiveServices(this);
2043        mProviderMap = new ProviderMap(this);
2044
2045        // TODO: Move creation of battery stats service outside of activity manager service.
2046        File dataDir = Environment.getDataDirectory();
2047        File systemDir = new File(dataDir, "system");
2048        systemDir.mkdirs();
2049        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2050        mBatteryStatsService.getActiveStatistics().readLocked();
2051        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2052        mOnBattery = DEBUG_POWER ? true
2053                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2054        mBatteryStatsService.getActiveStatistics().setCallback(this);
2055
2056        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2057
2058        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2059
2060        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2061
2062        // User 0 is the first and only user that runs at boot.
2063        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2064        mUserLru.add(Integer.valueOf(0));
2065        updateStartedUserArrayLocked();
2066
2067        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2068            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2069
2070        mConfiguration.setToDefaults();
2071        mConfiguration.setLocale(Locale.getDefault());
2072
2073        mConfigurationSeq = mConfiguration.seq = 1;
2074        mProcessCpuTracker.init();
2075
2076        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2077        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2078        mStackSupervisor = new ActivityStackSupervisor(this);
2079        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2080
2081        mProcessCpuThread = new Thread("CpuTracker") {
2082            @Override
2083            public void run() {
2084                while (true) {
2085                    try {
2086                        try {
2087                            synchronized(this) {
2088                                final long now = SystemClock.uptimeMillis();
2089                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2090                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2091                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2092                                //        + ", write delay=" + nextWriteDelay);
2093                                if (nextWriteDelay < nextCpuDelay) {
2094                                    nextCpuDelay = nextWriteDelay;
2095                                }
2096                                if (nextCpuDelay > 0) {
2097                                    mProcessCpuMutexFree.set(true);
2098                                    this.wait(nextCpuDelay);
2099                                }
2100                            }
2101                        } catch (InterruptedException e) {
2102                        }
2103                        updateCpuStatsNow();
2104                    } catch (Exception e) {
2105                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2106                    }
2107                }
2108            }
2109        };
2110
2111        Watchdog.getInstance().addMonitor(this);
2112        Watchdog.getInstance().addThread(mHandler);
2113    }
2114
2115    public void setSystemServiceManager(SystemServiceManager mgr) {
2116        mSystemServiceManager = mgr;
2117    }
2118
2119    public void setInstaller(Installer installer) {
2120        mInstaller = installer;
2121    }
2122
2123    private void start() {
2124        Process.removeAllProcessGroups();
2125        mProcessCpuThread.start();
2126
2127        mBatteryStatsService.publish(mContext);
2128        mAppOpsService.publish(mContext);
2129        Slog.d("AppOps", "AppOpsService published");
2130        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2131    }
2132
2133    public void initPowerManagement() {
2134        mStackSupervisor.initPowerManagement();
2135        mBatteryStatsService.initPowerManagement();
2136    }
2137
2138    @Override
2139    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2140            throws RemoteException {
2141        if (code == SYSPROPS_TRANSACTION) {
2142            // We need to tell all apps about the system property change.
2143            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2144            synchronized(this) {
2145                final int NP = mProcessNames.getMap().size();
2146                for (int ip=0; ip<NP; ip++) {
2147                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2148                    final int NA = apps.size();
2149                    for (int ia=0; ia<NA; ia++) {
2150                        ProcessRecord app = apps.valueAt(ia);
2151                        if (app.thread != null) {
2152                            procs.add(app.thread.asBinder());
2153                        }
2154                    }
2155                }
2156            }
2157
2158            int N = procs.size();
2159            for (int i=0; i<N; i++) {
2160                Parcel data2 = Parcel.obtain();
2161                try {
2162                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2163                } catch (RemoteException e) {
2164                }
2165                data2.recycle();
2166            }
2167        }
2168        try {
2169            return super.onTransact(code, data, reply, flags);
2170        } catch (RuntimeException e) {
2171            // The activity manager only throws security exceptions, so let's
2172            // log all others.
2173            if (!(e instanceof SecurityException)) {
2174                Slog.wtf(TAG, "Activity Manager Crash", e);
2175            }
2176            throw e;
2177        }
2178    }
2179
2180    void updateCpuStats() {
2181        final long now = SystemClock.uptimeMillis();
2182        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2183            return;
2184        }
2185        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2186            synchronized (mProcessCpuThread) {
2187                mProcessCpuThread.notify();
2188            }
2189        }
2190    }
2191
2192    void updateCpuStatsNow() {
2193        synchronized (mProcessCpuTracker) {
2194            mProcessCpuMutexFree.set(false);
2195            final long now = SystemClock.uptimeMillis();
2196            boolean haveNewCpuStats = false;
2197
2198            if (MONITOR_CPU_USAGE &&
2199                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2200                mLastCpuTime.set(now);
2201                haveNewCpuStats = true;
2202                mProcessCpuTracker.update();
2203                //Slog.i(TAG, mProcessCpu.printCurrentState());
2204                //Slog.i(TAG, "Total CPU usage: "
2205                //        + mProcessCpu.getTotalCpuPercent() + "%");
2206
2207                // Slog the cpu usage if the property is set.
2208                if ("true".equals(SystemProperties.get("events.cpu"))) {
2209                    int user = mProcessCpuTracker.getLastUserTime();
2210                    int system = mProcessCpuTracker.getLastSystemTime();
2211                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2212                    int irq = mProcessCpuTracker.getLastIrqTime();
2213                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2214                    int idle = mProcessCpuTracker.getLastIdleTime();
2215
2216                    int total = user + system + iowait + irq + softIrq + idle;
2217                    if (total == 0) total = 1;
2218
2219                    EventLog.writeEvent(EventLogTags.CPU,
2220                            ((user+system+iowait+irq+softIrq) * 100) / total,
2221                            (user * 100) / total,
2222                            (system * 100) / total,
2223                            (iowait * 100) / total,
2224                            (irq * 100) / total,
2225                            (softIrq * 100) / total);
2226                }
2227            }
2228
2229            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2230            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2231            synchronized(bstats) {
2232                synchronized(mPidsSelfLocked) {
2233                    if (haveNewCpuStats) {
2234                        if (mOnBattery) {
2235                            int perc = bstats.startAddingCpuLocked();
2236                            int totalUTime = 0;
2237                            int totalSTime = 0;
2238                            final int N = mProcessCpuTracker.countStats();
2239                            for (int i=0; i<N; i++) {
2240                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2241                                if (!st.working) {
2242                                    continue;
2243                                }
2244                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2245                                int otherUTime = (st.rel_utime*perc)/100;
2246                                int otherSTime = (st.rel_stime*perc)/100;
2247                                totalUTime += otherUTime;
2248                                totalSTime += otherSTime;
2249                                if (pr != null) {
2250                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2251                                    if (ps == null || !ps.isActive()) {
2252                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2253                                                pr.info.uid, pr.processName);
2254                                    }
2255                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2256                                            st.rel_stime-otherSTime);
2257                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2258                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2259                                } else {
2260                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2261                                    if (ps == null || !ps.isActive()) {
2262                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2263                                                bstats.mapUid(st.uid), st.name);
2264                                    }
2265                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2266                                            st.rel_stime-otherSTime);
2267                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2268                                }
2269                            }
2270                            bstats.finishAddingCpuLocked(perc, totalUTime,
2271                                    totalSTime, cpuSpeedTimes);
2272                        }
2273                    }
2274                }
2275
2276                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2277                    mLastWriteTime = now;
2278                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2279                }
2280            }
2281        }
2282    }
2283
2284    @Override
2285    public void batteryNeedsCpuUpdate() {
2286        updateCpuStatsNow();
2287    }
2288
2289    @Override
2290    public void batteryPowerChanged(boolean onBattery) {
2291        // When plugging in, update the CPU stats first before changing
2292        // the plug state.
2293        updateCpuStatsNow();
2294        synchronized (this) {
2295            synchronized(mPidsSelfLocked) {
2296                mOnBattery = DEBUG_POWER ? true : onBattery;
2297            }
2298        }
2299    }
2300
2301    /**
2302     * Initialize the application bind args. These are passed to each
2303     * process when the bindApplication() IPC is sent to the process. They're
2304     * lazily setup to make sure the services are running when they're asked for.
2305     */
2306    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2307        if (mAppBindArgs == null) {
2308            mAppBindArgs = new HashMap<>();
2309
2310            // Isolated processes won't get this optimization, so that we don't
2311            // violate the rules about which services they have access to.
2312            if (!isolated) {
2313                // Setup the application init args
2314                mAppBindArgs.put("package", ServiceManager.getService("package"));
2315                mAppBindArgs.put("window", ServiceManager.getService("window"));
2316                mAppBindArgs.put(Context.ALARM_SERVICE,
2317                        ServiceManager.getService(Context.ALARM_SERVICE));
2318            }
2319        }
2320        return mAppBindArgs;
2321    }
2322
2323    final void setFocusedActivityLocked(ActivityRecord r) {
2324        if (mFocusedActivity != r) {
2325            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2326            mFocusedActivity = r;
2327            if (r.task != null && r.task.voiceInteractor != null) {
2328                startRunningVoiceLocked();
2329            } else {
2330                finishRunningVoiceLocked();
2331            }
2332            mStackSupervisor.setFocusedStack(r);
2333            if (r != null) {
2334                mWindowManager.setFocusedApp(r.appToken, true);
2335            }
2336            applyUpdateLockStateLocked(r);
2337        }
2338    }
2339
2340    final void clearFocusedActivity(ActivityRecord r) {
2341        if (mFocusedActivity == r) {
2342            mFocusedActivity = null;
2343        }
2344    }
2345
2346    @Override
2347    public void setFocusedStack(int stackId) {
2348        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2349        synchronized (ActivityManagerService.this) {
2350            ActivityStack stack = mStackSupervisor.getStack(stackId);
2351            if (stack != null) {
2352                ActivityRecord r = stack.topRunningActivityLocked(null);
2353                if (r != null) {
2354                    setFocusedActivityLocked(r);
2355                }
2356            }
2357        }
2358    }
2359
2360    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2361    @Override
2362    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2363        synchronized (ActivityManagerService.this) {
2364            if (listener != null) {
2365                mTaskStackListeners.register(listener);
2366            }
2367        }
2368    }
2369
2370    @Override
2371    public void notifyActivityDrawn(IBinder token) {
2372        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2373        synchronized (this) {
2374            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2375            if (r != null) {
2376                r.task.stack.notifyActivityDrawnLocked(r);
2377            }
2378        }
2379    }
2380
2381    final void applyUpdateLockStateLocked(ActivityRecord r) {
2382        // Modifications to the UpdateLock state are done on our handler, outside
2383        // the activity manager's locks.  The new state is determined based on the
2384        // state *now* of the relevant activity record.  The object is passed to
2385        // the handler solely for logging detail, not to be consulted/modified.
2386        final boolean nextState = r != null && r.immersive;
2387        mHandler.sendMessage(
2388                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2389    }
2390
2391    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2392        Message msg = Message.obtain();
2393        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2394        msg.obj = r.task.askedCompatMode ? null : r;
2395        mHandler.sendMessage(msg);
2396    }
2397
2398    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2399            String what, Object obj, ProcessRecord srcApp) {
2400        app.lastActivityTime = now;
2401
2402        if (app.activities.size() > 0) {
2403            // Don't want to touch dependent processes that are hosting activities.
2404            return index;
2405        }
2406
2407        int lrui = mLruProcesses.lastIndexOf(app);
2408        if (lrui < 0) {
2409            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2410                    + what + " " + obj + " from " + srcApp);
2411            return index;
2412        }
2413
2414        if (lrui >= index) {
2415            // Don't want to cause this to move dependent processes *back* in the
2416            // list as if they were less frequently used.
2417            return index;
2418        }
2419
2420        if (lrui >= mLruProcessActivityStart) {
2421            // Don't want to touch dependent processes that are hosting activities.
2422            return index;
2423        }
2424
2425        mLruProcesses.remove(lrui);
2426        if (index > 0) {
2427            index--;
2428        }
2429        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2430                + " in LRU list: " + app);
2431        mLruProcesses.add(index, app);
2432        return index;
2433    }
2434
2435    final void removeLruProcessLocked(ProcessRecord app) {
2436        int lrui = mLruProcesses.lastIndexOf(app);
2437        if (lrui >= 0) {
2438            if (!app.killed) {
2439                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2440                Process.killProcessQuiet(app.pid);
2441                Process.killProcessGroup(app.info.uid, app.pid);
2442            }
2443            if (lrui <= mLruProcessActivityStart) {
2444                mLruProcessActivityStart--;
2445            }
2446            if (lrui <= mLruProcessServiceStart) {
2447                mLruProcessServiceStart--;
2448            }
2449            mLruProcesses.remove(lrui);
2450        }
2451    }
2452
2453    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2454            ProcessRecord client) {
2455        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2456                || app.treatLikeActivity;
2457        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2458        if (!activityChange && hasActivity) {
2459            // The process has activities, so we are only allowing activity-based adjustments
2460            // to move it.  It should be kept in the front of the list with other
2461            // processes that have activities, and we don't want those to change their
2462            // order except due to activity operations.
2463            return;
2464        }
2465
2466        mLruSeq++;
2467        final long now = SystemClock.uptimeMillis();
2468        app.lastActivityTime = now;
2469
2470        // First a quick reject: if the app is already at the position we will
2471        // put it, then there is nothing to do.
2472        if (hasActivity) {
2473            final int N = mLruProcesses.size();
2474            if (N > 0 && mLruProcesses.get(N-1) == app) {
2475                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2476                return;
2477            }
2478        } else {
2479            if (mLruProcessServiceStart > 0
2480                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2481                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2482                return;
2483            }
2484        }
2485
2486        int lrui = mLruProcesses.lastIndexOf(app);
2487
2488        if (app.persistent && lrui >= 0) {
2489            // We don't care about the position of persistent processes, as long as
2490            // they are in the list.
2491            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2492            return;
2493        }
2494
2495        /* In progress: compute new position first, so we can avoid doing work
2496           if the process is not actually going to move.  Not yet working.
2497        int addIndex;
2498        int nextIndex;
2499        boolean inActivity = false, inService = false;
2500        if (hasActivity) {
2501            // Process has activities, put it at the very tipsy-top.
2502            addIndex = mLruProcesses.size();
2503            nextIndex = mLruProcessServiceStart;
2504            inActivity = true;
2505        } else if (hasService) {
2506            // Process has services, put it at the top of the service list.
2507            addIndex = mLruProcessActivityStart;
2508            nextIndex = mLruProcessServiceStart;
2509            inActivity = true;
2510            inService = true;
2511        } else  {
2512            // Process not otherwise of interest, it goes to the top of the non-service area.
2513            addIndex = mLruProcessServiceStart;
2514            if (client != null) {
2515                int clientIndex = mLruProcesses.lastIndexOf(client);
2516                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2517                        + app);
2518                if (clientIndex >= 0 && addIndex > clientIndex) {
2519                    addIndex = clientIndex;
2520                }
2521            }
2522            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2523        }
2524
2525        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2526                + mLruProcessActivityStart + "): " + app);
2527        */
2528
2529        if (lrui >= 0) {
2530            if (lrui < mLruProcessActivityStart) {
2531                mLruProcessActivityStart--;
2532            }
2533            if (lrui < mLruProcessServiceStart) {
2534                mLruProcessServiceStart--;
2535            }
2536            /*
2537            if (addIndex > lrui) {
2538                addIndex--;
2539            }
2540            if (nextIndex > lrui) {
2541                nextIndex--;
2542            }
2543            */
2544            mLruProcesses.remove(lrui);
2545        }
2546
2547        /*
2548        mLruProcesses.add(addIndex, app);
2549        if (inActivity) {
2550            mLruProcessActivityStart++;
2551        }
2552        if (inService) {
2553            mLruProcessActivityStart++;
2554        }
2555        */
2556
2557        int nextIndex;
2558        if (hasActivity) {
2559            final int N = mLruProcesses.size();
2560            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2561                // Process doesn't have activities, but has clients with
2562                // activities...  move it up, but one below the top (the top
2563                // should always have a real activity).
2564                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2565                mLruProcesses.add(N-1, app);
2566                // To keep it from spamming the LRU list (by making a bunch of clients),
2567                // we will push down any other entries owned by the app.
2568                final int uid = app.info.uid;
2569                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2570                    ProcessRecord subProc = mLruProcesses.get(i);
2571                    if (subProc.info.uid == uid) {
2572                        // We want to push this one down the list.  If the process after
2573                        // it is for the same uid, however, don't do so, because we don't
2574                        // want them internally to be re-ordered.
2575                        if (mLruProcesses.get(i-1).info.uid != uid) {
2576                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2577                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2578                            ProcessRecord tmp = mLruProcesses.get(i);
2579                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2580                            mLruProcesses.set(i-1, tmp);
2581                            i--;
2582                        }
2583                    } else {
2584                        // A gap, we can stop here.
2585                        break;
2586                    }
2587                }
2588            } else {
2589                // Process has activities, put it at the very tipsy-top.
2590                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2591                mLruProcesses.add(app);
2592            }
2593            nextIndex = mLruProcessServiceStart;
2594        } else if (hasService) {
2595            // Process has services, put it at the top of the service list.
2596            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2597            mLruProcesses.add(mLruProcessActivityStart, app);
2598            nextIndex = mLruProcessServiceStart;
2599            mLruProcessActivityStart++;
2600        } else  {
2601            // Process not otherwise of interest, it goes to the top of the non-service area.
2602            int index = mLruProcessServiceStart;
2603            if (client != null) {
2604                // If there is a client, don't allow the process to be moved up higher
2605                // in the list than that client.
2606                int clientIndex = mLruProcesses.lastIndexOf(client);
2607                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2608                        + " when updating " + app);
2609                if (clientIndex <= lrui) {
2610                    // Don't allow the client index restriction to push it down farther in the
2611                    // list than it already is.
2612                    clientIndex = lrui;
2613                }
2614                if (clientIndex >= 0 && index > clientIndex) {
2615                    index = clientIndex;
2616                }
2617            }
2618            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2619            mLruProcesses.add(index, app);
2620            nextIndex = index-1;
2621            mLruProcessActivityStart++;
2622            mLruProcessServiceStart++;
2623        }
2624
2625        // If the app is currently using a content provider or service,
2626        // bump those processes as well.
2627        for (int j=app.connections.size()-1; j>=0; j--) {
2628            ConnectionRecord cr = app.connections.valueAt(j);
2629            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2630                    && cr.binding.service.app != null
2631                    && cr.binding.service.app.lruSeq != mLruSeq
2632                    && !cr.binding.service.app.persistent) {
2633                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2634                        "service connection", cr, app);
2635            }
2636        }
2637        for (int j=app.conProviders.size()-1; j>=0; j--) {
2638            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2639            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2640                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2641                        "provider reference", cpr, app);
2642            }
2643        }
2644    }
2645
2646    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2647        if (uid == Process.SYSTEM_UID) {
2648            // The system gets to run in any process.  If there are multiple
2649            // processes with the same uid, just pick the first (this
2650            // should never happen).
2651            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2652            if (procs == null) return null;
2653            final int N = procs.size();
2654            for (int i = 0; i < N; i++) {
2655                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2656            }
2657        }
2658        ProcessRecord proc = mProcessNames.get(processName, uid);
2659        if (false && proc != null && !keepIfLarge
2660                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2661                && proc.lastCachedPss >= 4000) {
2662            // Turn this condition on to cause killing to happen regularly, for testing.
2663            if (proc.baseProcessTracker != null) {
2664                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2665            }
2666            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2667        } else if (proc != null && !keepIfLarge
2668                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2669                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2670            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2671            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2672                if (proc.baseProcessTracker != null) {
2673                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2674                }
2675                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2676            }
2677        }
2678        return proc;
2679    }
2680
2681    void ensurePackageDexOpt(String packageName) {
2682        IPackageManager pm = AppGlobals.getPackageManager();
2683        try {
2684            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2685                mDidDexOpt = true;
2686            }
2687        } catch (RemoteException e) {
2688        }
2689    }
2690
2691    boolean isNextTransitionForward() {
2692        int transit = mWindowManager.getPendingAppTransition();
2693        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2694                || transit == AppTransition.TRANSIT_TASK_OPEN
2695                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2696    }
2697
2698    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2699            String processName, String abiOverride, int uid, Runnable crashHandler) {
2700        synchronized(this) {
2701            ApplicationInfo info = new ApplicationInfo();
2702            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2703            // For isolated processes, the former contains the parent's uid and the latter the
2704            // actual uid of the isolated process.
2705            // In the special case introduced by this method (which is, starting an isolated
2706            // process directly from the SystemServer without an actual parent app process) the
2707            // closest thing to a parent's uid is SYSTEM_UID.
2708            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2709            // the |isolated| logic in the ProcessRecord constructor.
2710            info.uid = Process.SYSTEM_UID;
2711            info.processName = processName;
2712            info.className = entryPoint;
2713            info.packageName = "android";
2714            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2715                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2716                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2717                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2718                    crashHandler);
2719            return proc != null ? proc.pid : 0;
2720        }
2721    }
2722
2723    final ProcessRecord startProcessLocked(String processName,
2724            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2725            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2726            boolean isolated, boolean keepIfLarge) {
2727        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2728                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2729                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2730                null /* crashHandler */);
2731    }
2732
2733    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2734            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2735            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2736            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2737        long startTime = SystemClock.elapsedRealtime();
2738        ProcessRecord app;
2739        if (!isolated) {
2740            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2741            checkTime(startTime, "startProcess: after getProcessRecord");
2742        } else {
2743            // If this is an isolated process, it can't re-use an existing process.
2744            app = null;
2745        }
2746        // We don't have to do anything more if:
2747        // (1) There is an existing application record; and
2748        // (2) The caller doesn't think it is dead, OR there is no thread
2749        //     object attached to it so we know it couldn't have crashed; and
2750        // (3) There is a pid assigned to it, so it is either starting or
2751        //     already running.
2752        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2753                + " app=" + app + " knownToBeDead=" + knownToBeDead
2754                + " thread=" + (app != null ? app.thread : null)
2755                + " pid=" + (app != null ? app.pid : -1));
2756        if (app != null && app.pid > 0) {
2757            if (!knownToBeDead || app.thread == null) {
2758                // We already have the app running, or are waiting for it to
2759                // come up (we have a pid but not yet its thread), so keep it.
2760                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2761                // If this is a new package in the process, add the package to the list
2762                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2763                checkTime(startTime, "startProcess: done, added package to proc");
2764                return app;
2765            }
2766
2767            // An application record is attached to a previous process,
2768            // clean it up now.
2769            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2770            checkTime(startTime, "startProcess: bad proc running, killing");
2771            Process.killProcessGroup(app.info.uid, app.pid);
2772            handleAppDiedLocked(app, true, true);
2773            checkTime(startTime, "startProcess: done killing old proc");
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            checkTime(startTime, "startProcess: creating new process record");
2810            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2811            if (app == null) {
2812                Slog.w(TAG, "Failed making new process record for "
2813                        + processName + "/" + info.uid + " isolated=" + isolated);
2814                return null;
2815            }
2816            app.crashHandler = crashHandler;
2817            mProcessNames.put(processName, app.uid, app);
2818            if (isolated) {
2819                mIsolatedProcesses.put(app.uid, app);
2820            }
2821            checkTime(startTime, "startProcess: done creating new process record");
2822        } else {
2823            // If this is a new package in the process, add the package to the list
2824            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2825            checkTime(startTime, "startProcess: added package to existing proc");
2826        }
2827
2828        // If the system is not ready yet, then hold off on starting this
2829        // process until it is.
2830        if (!mProcessesReady
2831                && !isAllowedWhileBooting(info)
2832                && !allowWhileBooting) {
2833            if (!mProcessesOnHold.contains(app)) {
2834                mProcessesOnHold.add(app);
2835            }
2836            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2837            checkTime(startTime, "startProcess: returning with proc on hold");
2838            return app;
2839        }
2840
2841        checkTime(startTime, "startProcess: stepping in to startProcess");
2842        startProcessLocked(
2843                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2844        checkTime(startTime, "startProcess: done starting proc!");
2845        return (app.pid != 0) ? app : null;
2846    }
2847
2848    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2849        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2850    }
2851
2852    private final void startProcessLocked(ProcessRecord app,
2853            String hostingType, String hostingNameStr) {
2854        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2855                null /* entryPoint */, null /* entryPointArgs */);
2856    }
2857
2858    private final void startProcessLocked(ProcessRecord app, String hostingType,
2859            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2860        long startTime = SystemClock.elapsedRealtime();
2861        if (app.pid > 0 && app.pid != MY_PID) {
2862            checkTime(startTime, "startProcess: removing from pids map");
2863            synchronized (mPidsSelfLocked) {
2864                mPidsSelfLocked.remove(app.pid);
2865                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2866            }
2867            checkTime(startTime, "startProcess: done removing from pids map");
2868            app.setPid(0);
2869        }
2870
2871        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2872                "startProcessLocked removing on hold: " + app);
2873        mProcessesOnHold.remove(app);
2874
2875        checkTime(startTime, "startProcess: starting to update cpu stats");
2876        updateCpuStats();
2877        checkTime(startTime, "startProcess: done updating cpu stats");
2878
2879        try {
2880            int uid = app.uid;
2881
2882            int[] gids = null;
2883            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2884            if (!app.isolated) {
2885                int[] permGids = null;
2886                try {
2887                    checkTime(startTime, "startProcess: getting gids from package manager");
2888                    final PackageManager pm = mContext.getPackageManager();
2889                    permGids = pm.getPackageGids(app.info.packageName);
2890
2891                    if (Environment.isExternalStorageEmulated()) {
2892                        checkTime(startTime, "startProcess: checking external storage perm");
2893                        if (pm.checkPermission(
2894                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2895                                app.info.packageName) == PERMISSION_GRANTED) {
2896                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2897                        } else {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2899                        }
2900                    }
2901                } catch (PackageManager.NameNotFoundException e) {
2902                    Slog.w(TAG, "Unable to retrieve gids", e);
2903                }
2904
2905                /*
2906                 * Add shared application and profile GIDs so applications can share some
2907                 * resources like shared libraries and access user-wide resources
2908                 */
2909                if (permGids == null) {
2910                    gids = new int[2];
2911                } else {
2912                    gids = new int[permGids.length + 2];
2913                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2914                }
2915                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2916                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2917            }
2918            checkTime(startTime, "startProcess: building args");
2919            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2920                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2921                        && mTopComponent != null
2922                        && app.processName.equals(mTopComponent.getPackageName())) {
2923                    uid = 0;
2924                }
2925                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2926                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2927                    uid = 0;
2928                }
2929            }
2930            int debugFlags = 0;
2931            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2932                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2933                // Also turn on CheckJNI for debuggable apps. It's quite
2934                // awkward to turn on otherwise.
2935                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2936            }
2937            // Run the app in safe mode if its manifest requests so or the
2938            // system is booted in safe mode.
2939            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2940                mSafeMode == true) {
2941                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2942            }
2943            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2944                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2945            }
2946            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2947                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2948            }
2949            if ("1".equals(SystemProperties.get("debug.assert"))) {
2950                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2951            }
2952
2953            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2954            if (requiredAbi == null) {
2955                requiredAbi = Build.SUPPORTED_ABIS[0];
2956            }
2957
2958            String instructionSet = null;
2959            if (app.info.primaryCpuAbi != null) {
2960                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2961            }
2962
2963            // Start the process.  It will either succeed and return a result containing
2964            // the PID of the new process, or else throw a RuntimeException.
2965            boolean isActivityProcess = (entryPoint == null);
2966            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2967            checkTime(startTime, "startProcess: asking zygote to start proc");
2968            Process.ProcessStartResult startResult = Process.start(entryPoint,
2969                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2970                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2971                    app.info.dataDir, entryPointArgs);
2972            checkTime(startTime, "startProcess: returned from zygote!");
2973
2974            if (app.isolated) {
2975                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2976            }
2977            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2978            checkTime(startTime, "startProcess: done updating battery stats");
2979
2980            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2981                    UserHandle.getUserId(uid), startResult.pid, uid,
2982                    app.processName, hostingType,
2983                    hostingNameStr != null ? hostingNameStr : "");
2984
2985            if (app.persistent) {
2986                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2987            }
2988
2989            checkTime(startTime, "startProcess: building log message");
2990            StringBuilder buf = mStringBuilder;
2991            buf.setLength(0);
2992            buf.append("Start proc ");
2993            buf.append(app.processName);
2994            if (!isActivityProcess) {
2995                buf.append(" [");
2996                buf.append(entryPoint);
2997                buf.append("]");
2998            }
2999            buf.append(" for ");
3000            buf.append(hostingType);
3001            if (hostingNameStr != null) {
3002                buf.append(" ");
3003                buf.append(hostingNameStr);
3004            }
3005            buf.append(": pid=");
3006            buf.append(startResult.pid);
3007            buf.append(" uid=");
3008            buf.append(uid);
3009            buf.append(" gids={");
3010            if (gids != null) {
3011                for (int gi=0; gi<gids.length; gi++) {
3012                    if (gi != 0) buf.append(", ");
3013                    buf.append(gids[gi]);
3014
3015                }
3016            }
3017            buf.append("}");
3018            if (requiredAbi != null) {
3019                buf.append(" abi=");
3020                buf.append(requiredAbi);
3021            }
3022            Slog.i(TAG, buf.toString());
3023            app.setPid(startResult.pid);
3024            app.usingWrapper = startResult.usingWrapper;
3025            app.removed = false;
3026            app.killed = false;
3027            app.killedByAm = false;
3028            checkTime(startTime, "startProcess: starting to update pids map");
3029            synchronized (mPidsSelfLocked) {
3030                this.mPidsSelfLocked.put(startResult.pid, app);
3031                if (isActivityProcess) {
3032                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3033                    msg.obj = app;
3034                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3035                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3036                }
3037            }
3038            checkTime(startTime, "startProcess: done updating pids map");
3039        } catch (RuntimeException e) {
3040            // XXX do better error recovery.
3041            app.setPid(0);
3042            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3043            if (app.isolated) {
3044                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3045            }
3046            Slog.e(TAG, "Failure starting process " + app.processName, e);
3047        }
3048    }
3049
3050    void updateUsageStats(ActivityRecord component, boolean resumed) {
3051        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3052        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3053        if (resumed) {
3054            if (mUsageStatsService != null) {
3055                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3056                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3057            }
3058            synchronized (stats) {
3059                stats.noteActivityResumedLocked(component.app.uid);
3060            }
3061        } else {
3062            if (mUsageStatsService != null) {
3063                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3064                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3065            }
3066            synchronized (stats) {
3067                stats.noteActivityPausedLocked(component.app.uid);
3068            }
3069        }
3070    }
3071
3072    Intent getHomeIntent() {
3073        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3074        intent.setComponent(mTopComponent);
3075        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3076            intent.addCategory(Intent.CATEGORY_HOME);
3077        }
3078        return intent;
3079    }
3080
3081    boolean startHomeActivityLocked(int userId) {
3082        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3083                && mTopAction == null) {
3084            // We are running in factory test mode, but unable to find
3085            // the factory test app, so just sit around displaying the
3086            // error message and don't try to start anything.
3087            return false;
3088        }
3089        Intent intent = getHomeIntent();
3090        ActivityInfo aInfo =
3091            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3092        if (aInfo != null) {
3093            intent.setComponent(new ComponentName(
3094                    aInfo.applicationInfo.packageName, aInfo.name));
3095            // Don't do this if the home app is currently being
3096            // instrumented.
3097            aInfo = new ActivityInfo(aInfo);
3098            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3099            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3100                    aInfo.applicationInfo.uid, true);
3101            if (app == null || app.instrumentationClass == null) {
3102                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3103                mStackSupervisor.startHomeActivity(intent, aInfo);
3104            }
3105        }
3106
3107        return true;
3108    }
3109
3110    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3111        ActivityInfo ai = null;
3112        ComponentName comp = intent.getComponent();
3113        try {
3114            if (comp != null) {
3115                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3116            } else {
3117                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3118                        intent,
3119                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3120                            flags, userId);
3121
3122                if (info != null) {
3123                    ai = info.activityInfo;
3124                }
3125            }
3126        } catch (RemoteException e) {
3127            // ignore
3128        }
3129
3130        return ai;
3131    }
3132
3133    /**
3134     * Starts the "new version setup screen" if appropriate.
3135     */
3136    void startSetupActivityLocked() {
3137        // Only do this once per boot.
3138        if (mCheckedForSetup) {
3139            return;
3140        }
3141
3142        // We will show this screen if the current one is a different
3143        // version than the last one shown, and we are not running in
3144        // low-level factory test mode.
3145        final ContentResolver resolver = mContext.getContentResolver();
3146        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3147                Settings.Global.getInt(resolver,
3148                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3149            mCheckedForSetup = true;
3150
3151            // See if we should be showing the platform update setup UI.
3152            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3153            List<ResolveInfo> ris = mContext.getPackageManager()
3154                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3155
3156            // We don't allow third party apps to replace this.
3157            ResolveInfo ri = null;
3158            for (int i=0; ris != null && i<ris.size(); i++) {
3159                if ((ris.get(i).activityInfo.applicationInfo.flags
3160                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3161                    ri = ris.get(i);
3162                    break;
3163                }
3164            }
3165
3166            if (ri != null) {
3167                String vers = ri.activityInfo.metaData != null
3168                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3169                        : null;
3170                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3171                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3172                            Intent.METADATA_SETUP_VERSION);
3173                }
3174                String lastVers = Settings.Secure.getString(
3175                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3176                if (vers != null && !vers.equals(lastVers)) {
3177                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3178                    intent.setComponent(new ComponentName(
3179                            ri.activityInfo.packageName, ri.activityInfo.name));
3180                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3181                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3182                            null);
3183                }
3184            }
3185        }
3186    }
3187
3188    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3189        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3190    }
3191
3192    void enforceNotIsolatedCaller(String caller) {
3193        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3194            throw new SecurityException("Isolated process not allowed to call " + caller);
3195        }
3196    }
3197
3198    void enforceShellRestriction(String restriction, int userHandle) {
3199        if (Binder.getCallingUid() == Process.SHELL_UID) {
3200            if (userHandle < 0
3201                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3202                throw new SecurityException("Shell does not have permission to access user "
3203                        + userHandle);
3204            }
3205        }
3206    }
3207
3208    @Override
3209    public int getFrontActivityScreenCompatMode() {
3210        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3211        synchronized (this) {
3212            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3213        }
3214    }
3215
3216    @Override
3217    public void setFrontActivityScreenCompatMode(int mode) {
3218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3219                "setFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3222        }
3223    }
3224
3225    @Override
3226    public int getPackageScreenCompatMode(String packageName) {
3227        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3228        synchronized (this) {
3229            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3230        }
3231    }
3232
3233    @Override
3234    public void setPackageScreenCompatMode(String packageName, int mode) {
3235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3236                "setPackageScreenCompatMode");
3237        synchronized (this) {
3238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3239        }
3240    }
3241
3242    @Override
3243    public boolean getPackageAskScreenCompat(String packageName) {
3244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3245        synchronized (this) {
3246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3247        }
3248    }
3249
3250    @Override
3251    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setPackageAskScreenCompat");
3254        synchronized (this) {
3255            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3256        }
3257    }
3258
3259    private void dispatchProcessesChanged() {
3260        int N;
3261        synchronized (this) {
3262            N = mPendingProcessChanges.size();
3263            if (mActiveProcessChanges.length < N) {
3264                mActiveProcessChanges = new ProcessChangeItem[N];
3265            }
3266            mPendingProcessChanges.toArray(mActiveProcessChanges);
3267            mAvailProcessChanges.addAll(mPendingProcessChanges);
3268            mPendingProcessChanges.clear();
3269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3270        }
3271
3272        int i = mProcessObservers.beginBroadcast();
3273        while (i > 0) {
3274            i--;
3275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3276            if (observer != null) {
3277                try {
3278                    for (int j=0; j<N; j++) {
3279                        ProcessChangeItem item = mActiveProcessChanges[j];
3280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3282                                    + item.pid + " uid=" + item.uid + ": "
3283                                    + item.foregroundActivities);
3284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3285                                    item.foregroundActivities);
3286                        }
3287                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3289                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3290                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3291                        }
3292                    }
3293                } catch (RemoteException e) {
3294                }
3295            }
3296        }
3297        mProcessObservers.finishBroadcast();
3298    }
3299
3300    private void dispatchProcessDied(int pid, int uid) {
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    observer.onProcessDied(pid, uid);
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    @Override
3316    public final int startActivity(IApplicationThread caller, String callingPackage,
3317            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3318            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3319        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3320            resultWho, requestCode, startFlags, profilerInfo, options,
3321            UserHandle.getCallingUserId());
3322    }
3323
3324    @Override
3325    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3326            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3327            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3328        enforceNotIsolatedCaller("startActivity");
3329        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3330                false, ALLOW_FULL_ONLY, "startActivity", null);
3331        // TODO: Switch to user app stacks here.
3332        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3333                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3334                profilerInfo, null, null, options, userId, null, null);
3335    }
3336
3337    @Override
3338    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3339            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3340            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3341
3342        // This is very dangerous -- it allows you to perform a start activity (including
3343        // permission grants) as any app that may launch one of your own activities.  So
3344        // we will only allow this to be done from activities that are part of the core framework,
3345        // and then only when they are running as the system.
3346        final ActivityRecord sourceRecord;
3347        final int targetUid;
3348        final String targetPackage;
3349        synchronized (this) {
3350            if (resultTo == null) {
3351                throw new SecurityException("Must be called from an activity");
3352            }
3353            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3354            if (sourceRecord == null) {
3355                throw new SecurityException("Called with bad activity token: " + resultTo);
3356            }
3357            if (!sourceRecord.info.packageName.equals("android")) {
3358                throw new SecurityException(
3359                        "Must be called from an activity that is declared in the android package");
3360            }
3361            if (sourceRecord.app == null) {
3362                throw new SecurityException("Called without a process attached to activity");
3363            }
3364            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3365                // This is still okay, as long as this activity is running under the
3366                // uid of the original calling activity.
3367                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3368                    throw new SecurityException(
3369                            "Calling activity in uid " + sourceRecord.app.uid
3370                                    + " must be system uid or original calling uid "
3371                                    + sourceRecord.launchedFromUid);
3372                }
3373            }
3374            targetUid = sourceRecord.launchedFromUid;
3375            targetPackage = sourceRecord.launchedFromPackage;
3376        }
3377
3378        if (userId == UserHandle.USER_NULL) {
3379            userId = UserHandle.getUserId(sourceRecord.app.uid);
3380        }
3381
3382        // TODO: Switch to user app stacks here.
3383        try {
3384            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3385                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3386                    null, null, options, userId, null, null);
3387            return ret;
3388        } catch (SecurityException e) {
3389            // XXX need to figure out how to propagate to original app.
3390            // A SecurityException here is generally actually a fault of the original
3391            // calling activity (such as a fairly granting permissions), so propagate it
3392            // back to them.
3393            /*
3394            StringBuilder msg = new StringBuilder();
3395            msg.append("While launching");
3396            msg.append(intent.toString());
3397            msg.append(": ");
3398            msg.append(e.getMessage());
3399            */
3400            throw e;
3401        }
3402    }
3403
3404    @Override
3405    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3406            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3407            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3408        enforceNotIsolatedCaller("startActivityAndWait");
3409        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3410                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3411        WaitResult res = new WaitResult();
3412        // TODO: Switch to user app stacks here.
3413        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3414                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3415                options, userId, null, null);
3416        return res;
3417    }
3418
3419    @Override
3420    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3421            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3422            int startFlags, Configuration config, Bundle options, int userId) {
3423        enforceNotIsolatedCaller("startActivityWithConfig");
3424        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3425                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3426        // TODO: Switch to user app stacks here.
3427        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3428                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3429                null, null, config, options, userId, null, null);
3430        return ret;
3431    }
3432
3433    @Override
3434    public int startActivityIntentSender(IApplicationThread caller,
3435            IntentSender intent, Intent fillInIntent, String resolvedType,
3436            IBinder resultTo, String resultWho, int requestCode,
3437            int flagsMask, int flagsValues, Bundle options) {
3438        enforceNotIsolatedCaller("startActivityIntentSender");
3439        // Refuse possible leaked file descriptors
3440        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3441            throw new IllegalArgumentException("File descriptors passed in Intent");
3442        }
3443
3444        IIntentSender sender = intent.getTarget();
3445        if (!(sender instanceof PendingIntentRecord)) {
3446            throw new IllegalArgumentException("Bad PendingIntent object");
3447        }
3448
3449        PendingIntentRecord pir = (PendingIntentRecord)sender;
3450
3451        synchronized (this) {
3452            // If this is coming from the currently resumed activity, it is
3453            // effectively saying that app switches are allowed at this point.
3454            final ActivityStack stack = getFocusedStack();
3455            if (stack.mResumedActivity != null &&
3456                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3457                mAppSwitchesAllowedTime = 0;
3458            }
3459        }
3460        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3461                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3462        return ret;
3463    }
3464
3465    @Override
3466    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3467            Intent intent, String resolvedType, IVoiceInteractionSession session,
3468            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3469            Bundle options, int userId) {
3470        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3471                != PackageManager.PERMISSION_GRANTED) {
3472            String msg = "Permission Denial: startVoiceActivity() from pid="
3473                    + Binder.getCallingPid()
3474                    + ", uid=" + Binder.getCallingUid()
3475                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3476            Slog.w(TAG, msg);
3477            throw new SecurityException(msg);
3478        }
3479        if (session == null || interactor == null) {
3480            throw new NullPointerException("null session or interactor");
3481        }
3482        userId = handleIncomingUser(callingPid, callingUid, userId,
3483                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3484        // TODO: Switch to user app stacks here.
3485        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3486                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3487                null, options, userId, null, null);
3488    }
3489
3490    @Override
3491    public boolean startNextMatchingActivity(IBinder callingActivity,
3492            Intent intent, Bundle options) {
3493        // Refuse possible leaked file descriptors
3494        if (intent != null && intent.hasFileDescriptors() == true) {
3495            throw new IllegalArgumentException("File descriptors passed in Intent");
3496        }
3497
3498        synchronized (this) {
3499            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3500            if (r == null) {
3501                ActivityOptions.abort(options);
3502                return false;
3503            }
3504            if (r.app == null || r.app.thread == null) {
3505                // The caller is not running...  d'oh!
3506                ActivityOptions.abort(options);
3507                return false;
3508            }
3509            intent = new Intent(intent);
3510            // The caller is not allowed to change the data.
3511            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3512            // And we are resetting to find the next component...
3513            intent.setComponent(null);
3514
3515            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3516
3517            ActivityInfo aInfo = null;
3518            try {
3519                List<ResolveInfo> resolves =
3520                    AppGlobals.getPackageManager().queryIntentActivities(
3521                            intent, r.resolvedType,
3522                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3523                            UserHandle.getCallingUserId());
3524
3525                // Look for the original activity in the list...
3526                final int N = resolves != null ? resolves.size() : 0;
3527                for (int i=0; i<N; i++) {
3528                    ResolveInfo rInfo = resolves.get(i);
3529                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3530                            && rInfo.activityInfo.name.equals(r.info.name)) {
3531                        // We found the current one...  the next matching is
3532                        // after it.
3533                        i++;
3534                        if (i<N) {
3535                            aInfo = resolves.get(i).activityInfo;
3536                        }
3537                        if (debug) {
3538                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3539                                    + "/" + r.info.name);
3540                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3541                                    + "/" + aInfo.name);
3542                        }
3543                        break;
3544                    }
3545                }
3546            } catch (RemoteException e) {
3547            }
3548
3549            if (aInfo == null) {
3550                // Nobody who is next!
3551                ActivityOptions.abort(options);
3552                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3553                return false;
3554            }
3555
3556            intent.setComponent(new ComponentName(
3557                    aInfo.applicationInfo.packageName, aInfo.name));
3558            intent.setFlags(intent.getFlags()&~(
3559                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3560                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3561                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3562                    Intent.FLAG_ACTIVITY_NEW_TASK));
3563
3564            // Okay now we need to start the new activity, replacing the
3565            // currently running activity.  This is a little tricky because
3566            // we want to start the new one as if the current one is finished,
3567            // but not finish the current one first so that there is no flicker.
3568            // And thus...
3569            final boolean wasFinishing = r.finishing;
3570            r.finishing = true;
3571
3572            // Propagate reply information over to the new activity.
3573            final ActivityRecord resultTo = r.resultTo;
3574            final String resultWho = r.resultWho;
3575            final int requestCode = r.requestCode;
3576            r.resultTo = null;
3577            if (resultTo != null) {
3578                resultTo.removeResultsLocked(r, resultWho, requestCode);
3579            }
3580
3581            final long origId = Binder.clearCallingIdentity();
3582            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3583                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3584                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3585                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3586            Binder.restoreCallingIdentity(origId);
3587
3588            r.finishing = wasFinishing;
3589            if (res != ActivityManager.START_SUCCESS) {
3590                return false;
3591            }
3592            return true;
3593        }
3594    }
3595
3596    @Override
3597    public final int startActivityFromRecents(int taskId, Bundle options) {
3598        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3599            String msg = "Permission Denial: startActivityFromRecents called without " +
3600                    START_TASKS_FROM_RECENTS;
3601            Slog.w(TAG, msg);
3602            throw new SecurityException(msg);
3603        }
3604        return startActivityFromRecentsInner(taskId, options);
3605    }
3606
3607    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3608        final TaskRecord task;
3609        final int callingUid;
3610        final String callingPackage;
3611        final Intent intent;
3612        final int userId;
3613        synchronized (this) {
3614            task = recentTaskForIdLocked(taskId);
3615            if (task == null) {
3616                throw new IllegalArgumentException("Task " + taskId + " not found.");
3617            }
3618            callingUid = task.mCallingUid;
3619            callingPackage = task.mCallingPackage;
3620            intent = task.intent;
3621            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3622            userId = task.userId;
3623        }
3624        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3625                options, userId, null, task);
3626    }
3627
3628    final int startActivityInPackage(int uid, String callingPackage,
3629            Intent intent, String resolvedType, IBinder resultTo,
3630            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3631            IActivityContainer container, TaskRecord inTask) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635
3636        // TODO: Switch to user app stacks here.
3637        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3638                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3639                null, null, null, options, userId, container, inTask);
3640        return ret;
3641    }
3642
3643    @Override
3644    public final int startActivities(IApplicationThread caller, String callingPackage,
3645            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3646            int userId) {
3647        enforceNotIsolatedCaller("startActivities");
3648        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3649                false, ALLOW_FULL_ONLY, "startActivity", null);
3650        // TODO: Switch to user app stacks here.
3651        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3652                resolvedTypes, resultTo, options, userId);
3653        return ret;
3654    }
3655
3656    final int startActivitiesInPackage(int uid, String callingPackage,
3657            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3658            Bundle options, int userId) {
3659
3660        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3661                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3662        // TODO: Switch to user app stacks here.
3663        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3664                resultTo, options, userId);
3665        return ret;
3666    }
3667
3668    //explicitly remove thd old information in mRecentTasks when removing existing user.
3669    private void removeRecentTasksForUserLocked(int userId) {
3670        if(userId <= 0) {
3671            Slog.i(TAG, "Can't remove recent task on user " + userId);
3672            return;
3673        }
3674
3675        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3676            TaskRecord tr = mRecentTasks.get(i);
3677            if (tr.userId == userId) {
3678                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3679                        + " when finishing user" + userId);
3680                mRecentTasks.remove(i);
3681                tr.removedFromRecents();
3682            }
3683        }
3684
3685        // Remove tasks from persistent storage.
3686        notifyTaskPersisterLocked(null, true);
3687    }
3688
3689    // Sort by taskId
3690    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3691        @Override
3692        public int compare(TaskRecord lhs, TaskRecord rhs) {
3693            return rhs.taskId - lhs.taskId;
3694        }
3695    };
3696
3697    // Extract the affiliates of the chain containing mRecentTasks[start].
3698    private int processNextAffiliateChainLocked(int start) {
3699        final TaskRecord startTask = mRecentTasks.get(start);
3700        final int affiliateId = startTask.mAffiliatedTaskId;
3701
3702        // Quick identification of isolated tasks. I.e. those not launched behind.
3703        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3704                startTask.mNextAffiliate == null) {
3705            // There is still a slim chance that there are other tasks that point to this task
3706            // and that the chain is so messed up that this task no longer points to them but
3707            // the gain of this optimization outweighs the risk.
3708            startTask.inRecents = true;
3709            return start + 1;
3710        }
3711
3712        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3713        mTmpRecents.clear();
3714        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3715            final TaskRecord task = mRecentTasks.get(i);
3716            if (task.mAffiliatedTaskId == affiliateId) {
3717                mRecentTasks.remove(i);
3718                mTmpRecents.add(task);
3719            }
3720        }
3721
3722        // Sort them all by taskId. That is the order they were create in and that order will
3723        // always be correct.
3724        Collections.sort(mTmpRecents, mTaskRecordComparator);
3725
3726        // Go through and fix up the linked list.
3727        // The first one is the end of the chain and has no next.
3728        final TaskRecord first = mTmpRecents.get(0);
3729        first.inRecents = true;
3730        if (first.mNextAffiliate != null) {
3731            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3732            first.setNextAffiliate(null);
3733            notifyTaskPersisterLocked(first, false);
3734        }
3735        // Everything in the middle is doubly linked from next to prev.
3736        final int tmpSize = mTmpRecents.size();
3737        for (int i = 0; i < tmpSize - 1; ++i) {
3738            final TaskRecord next = mTmpRecents.get(i);
3739            final TaskRecord prev = mTmpRecents.get(i + 1);
3740            if (next.mPrevAffiliate != prev) {
3741                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3742                        " setting prev=" + prev);
3743                next.setPrevAffiliate(prev);
3744                notifyTaskPersisterLocked(next, false);
3745            }
3746            if (prev.mNextAffiliate != next) {
3747                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3748                        " setting next=" + next);
3749                prev.setNextAffiliate(next);
3750                notifyTaskPersisterLocked(prev, false);
3751            }
3752            prev.inRecents = true;
3753        }
3754        // The last one is the beginning of the list and has no prev.
3755        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3756        if (last.mPrevAffiliate != null) {
3757            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3758            last.setPrevAffiliate(null);
3759            notifyTaskPersisterLocked(last, false);
3760        }
3761
3762        // Insert the group back into mRecentTasks at start.
3763        mRecentTasks.addAll(start, mTmpRecents);
3764
3765        // Let the caller know where we left off.
3766        return start + tmpSize;
3767    }
3768
3769    /**
3770     * Update the recent tasks lists: make sure tasks should still be here (their
3771     * applications / activities still exist), update their availability, fixup ordering
3772     * of affiliations.
3773     */
3774    void cleanupRecentTasksLocked(int userId) {
3775        if (mRecentTasks == null) {
3776            // Happens when called from the packagemanager broadcast before boot.
3777            return;
3778        }
3779
3780        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3781        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3782        final IPackageManager pm = AppGlobals.getPackageManager();
3783        final ActivityInfo dummyAct = new ActivityInfo();
3784        final ApplicationInfo dummyApp = new ApplicationInfo();
3785
3786        int N = mRecentTasks.size();
3787
3788        int[] users = userId == UserHandle.USER_ALL
3789                ? getUsersLocked() : new int[] { userId };
3790        for (int user : users) {
3791            for (int i = 0; i < N; i++) {
3792                TaskRecord task = mRecentTasks.get(i);
3793                if (task.userId != user) {
3794                    // Only look at tasks for the user ID of interest.
3795                    continue;
3796                }
3797                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3798                    // This situation is broken, and we should just get rid of it now.
3799                    mRecentTasks.remove(i);
3800                    task.removedFromRecents();
3801                    i--;
3802                    N--;
3803                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3804                    continue;
3805                }
3806                // Check whether this activity is currently available.
3807                if (task.realActivity != null) {
3808                    ActivityInfo ai = availActCache.get(task.realActivity);
3809                    if (ai == null) {
3810                        try {
3811                            ai = pm.getActivityInfo(task.realActivity,
3812                                    PackageManager.GET_UNINSTALLED_PACKAGES
3813                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3814                        } catch (RemoteException e) {
3815                            // Will never happen.
3816                            continue;
3817                        }
3818                        if (ai == null) {
3819                            ai = dummyAct;
3820                        }
3821                        availActCache.put(task.realActivity, ai);
3822                    }
3823                    if (ai == dummyAct) {
3824                        // This could be either because the activity no longer exists, or the
3825                        // app is temporarily gone.  For the former we want to remove the recents
3826                        // entry; for the latter we want to mark it as unavailable.
3827                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3828                        if (app == null) {
3829                            try {
3830                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3831                                        PackageManager.GET_UNINSTALLED_PACKAGES
3832                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3833                            } catch (RemoteException e) {
3834                                // Will never happen.
3835                                continue;
3836                            }
3837                            if (app == null) {
3838                                app = dummyApp;
3839                            }
3840                            availAppCache.put(task.realActivity.getPackageName(), app);
3841                        }
3842                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3843                            // Doesn't exist any more!  Good-bye.
3844                            mRecentTasks.remove(i);
3845                            task.removedFromRecents();
3846                            i--;
3847                            N--;
3848                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3849                            continue;
3850                        } else {
3851                            // Otherwise just not available for now.
3852                            if (task.isAvailable) {
3853                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3854                                        + task);
3855                            }
3856                            task.isAvailable = false;
3857                        }
3858                    } else {
3859                        if (!ai.enabled || !ai.applicationInfo.enabled
3860                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3861                            if (task.isAvailable) {
3862                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3863                                        + task + " (enabled=" + ai.enabled + "/"
3864                                        + ai.applicationInfo.enabled +  " flags="
3865                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3866                            }
3867                            task.isAvailable = false;
3868                        } else {
3869                            if (!task.isAvailable) {
3870                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3871                                        + task);
3872                            }
3873                            task.isAvailable = true;
3874                        }
3875                    }
3876                }
3877            }
3878        }
3879
3880        // Verify the affiliate chain for each task.
3881        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3882        }
3883
3884        mTmpRecents.clear();
3885        // mRecentTasks is now in sorted, affiliated order.
3886    }
3887
3888    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3889        int N = mRecentTasks.size();
3890        TaskRecord top = task;
3891        int topIndex = taskIndex;
3892        while (top.mNextAffiliate != null && topIndex > 0) {
3893            top = top.mNextAffiliate;
3894            topIndex--;
3895        }
3896        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3897                + topIndex + " from intial " + taskIndex);
3898        // Find the end of the chain, doing a sanity check along the way.
3899        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3900        int endIndex = topIndex;
3901        TaskRecord prev = top;
3902        while (endIndex < N) {
3903            TaskRecord cur = mRecentTasks.get(endIndex);
3904            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3905                    + endIndex + " " + cur);
3906            if (cur == top) {
3907                // Verify start of the chain.
3908                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3909                    Slog.wtf(TAG, "Bad chain @" + endIndex
3910                            + ": first task has next affiliate: " + prev);
3911                    sane = false;
3912                    break;
3913                }
3914            } else {
3915                // Verify middle of the chain's next points back to the one before.
3916                if (cur.mNextAffiliate != prev
3917                        || cur.mNextAffiliateTaskId != prev.taskId) {
3918                    Slog.wtf(TAG, "Bad chain @" + endIndex
3919                            + ": middle task " + cur + " @" + endIndex
3920                            + " has bad next affiliate "
3921                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3922                            + ", expected " + prev);
3923                    sane = false;
3924                    break;
3925                }
3926            }
3927            if (cur.mPrevAffiliateTaskId == -1) {
3928                // Chain ends here.
3929                if (cur.mPrevAffiliate != null) {
3930                    Slog.wtf(TAG, "Bad chain @" + endIndex
3931                            + ": last task " + cur + " has previous affiliate "
3932                            + cur.mPrevAffiliate);
3933                    sane = false;
3934                }
3935                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3936                break;
3937            } else {
3938                // Verify middle of the chain's prev points to a valid item.
3939                if (cur.mPrevAffiliate == null) {
3940                    Slog.wtf(TAG, "Bad chain @" + endIndex
3941                            + ": task " + cur + " has previous affiliate "
3942                            + cur.mPrevAffiliate + " but should be id "
3943                            + cur.mPrevAffiliate);
3944                    sane = false;
3945                    break;
3946                }
3947            }
3948            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3949                Slog.wtf(TAG, "Bad chain @" + endIndex
3950                        + ": task " + cur + " has affiliated id "
3951                        + cur.mAffiliatedTaskId + " but should be "
3952                        + task.mAffiliatedTaskId);
3953                sane = false;
3954                break;
3955            }
3956            prev = cur;
3957            endIndex++;
3958            if (endIndex >= N) {
3959                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3960                        + ": last task " + prev);
3961                sane = false;
3962                break;
3963            }
3964        }
3965        if (sane) {
3966            if (endIndex < taskIndex) {
3967                Slog.wtf(TAG, "Bad chain @" + endIndex
3968                        + ": did not extend to task " + task + " @" + taskIndex);
3969                sane = false;
3970            }
3971        }
3972        if (sane) {
3973            // All looks good, we can just move all of the affiliated tasks
3974            // to the top.
3975            for (int i=topIndex; i<=endIndex; i++) {
3976                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3977                        + " from " + i + " to " + (i-topIndex));
3978                TaskRecord cur = mRecentTasks.remove(i);
3979                mRecentTasks.add(i-topIndex, cur);
3980            }
3981            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3982                    + " to " + endIndex);
3983            return true;
3984        }
3985
3986        // Whoops, couldn't do it.
3987        return false;
3988    }
3989
3990    final void addRecentTaskLocked(TaskRecord task) {
3991        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3992                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3993
3994        int N = mRecentTasks.size();
3995        // Quick case: check if the top-most recent task is the same.
3996        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3997            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3998            return;
3999        }
4000        // Another quick case: check if this is part of a set of affiliated
4001        // tasks that are at the top.
4002        if (isAffiliated && N > 0 && task.inRecents
4003                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4004            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4005                    + " at top when adding " + task);
4006            return;
4007        }
4008        // Another quick case: never add voice sessions.
4009        if (task.voiceSession != null) {
4010            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4011            return;
4012        }
4013
4014        boolean needAffiliationFix = false;
4015
4016        // Slightly less quick case: the task is already in recents, so all we need
4017        // to do is move it.
4018        if (task.inRecents) {
4019            int taskIndex = mRecentTasks.indexOf(task);
4020            if (taskIndex >= 0) {
4021                if (!isAffiliated) {
4022                    // Simple case: this is not an affiliated task, so we just move it to the front.
4023                    mRecentTasks.remove(taskIndex);
4024                    mRecentTasks.add(0, task);
4025                    notifyTaskPersisterLocked(task, false);
4026                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4027                            + " from " + taskIndex);
4028                    return;
4029                } else {
4030                    // More complicated: need to keep all affiliated tasks together.
4031                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4032                        // All went well.
4033                        return;
4034                    }
4035
4036                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4037                    // everything and then go through our general path of adding a new task.
4038                    needAffiliationFix = true;
4039                }
4040            } else {
4041                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4042                needAffiliationFix = true;
4043            }
4044        }
4045
4046        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4047        trimRecentsForTaskLocked(task, true);
4048
4049        N = mRecentTasks.size();
4050        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4051            final TaskRecord tr = mRecentTasks.remove(N - 1);
4052            tr.removedFromRecents();
4053            N--;
4054        }
4055        task.inRecents = true;
4056        if (!isAffiliated || needAffiliationFix) {
4057            // If this is a simple non-affiliated task, or we had some failure trying to
4058            // handle it as part of an affilated task, then just place it at the top.
4059            mRecentTasks.add(0, task);
4060        } else if (isAffiliated) {
4061            // If this is a new affiliated task, then move all of the affiliated tasks
4062            // to the front and insert this new one.
4063            TaskRecord other = task.mNextAffiliate;
4064            if (other == null) {
4065                other = task.mPrevAffiliate;
4066            }
4067            if (other != null) {
4068                int otherIndex = mRecentTasks.indexOf(other);
4069                if (otherIndex >= 0) {
4070                    // Insert new task at appropriate location.
4071                    int taskIndex;
4072                    if (other == task.mNextAffiliate) {
4073                        // We found the index of our next affiliation, which is who is
4074                        // before us in the list, so add after that point.
4075                        taskIndex = otherIndex+1;
4076                    } else {
4077                        // We found the index of our previous affiliation, which is who is
4078                        // after us in the list, so add at their position.
4079                        taskIndex = otherIndex;
4080                    }
4081                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4082                            + taskIndex + ": " + task);
4083                    mRecentTasks.add(taskIndex, task);
4084
4085                    // Now move everything to the front.
4086                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4087                        // All went well.
4088                        return;
4089                    }
4090
4091                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4092                    // everything and then go through our general path of adding a new task.
4093                    needAffiliationFix = true;
4094                } else {
4095                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4096                            + other);
4097                    needAffiliationFix = true;
4098                }
4099            } else {
4100                if (DEBUG_RECENTS) Slog.d(TAG,
4101                        "addRecent: adding affiliated task without next/prev:" + task);
4102                needAffiliationFix = true;
4103            }
4104        }
4105        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4106
4107        if (needAffiliationFix) {
4108            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4109            cleanupRecentTasksLocked(task.userId);
4110        }
4111    }
4112
4113    /**
4114     * If needed, remove oldest existing entries in recents that are for the same kind
4115     * of task as the given one.
4116     */
4117    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4118        int N = mRecentTasks.size();
4119        final Intent intent = task.intent;
4120        final boolean document = intent != null && intent.isDocument();
4121
4122        int maxRecents = task.maxRecents - 1;
4123        for (int i=0; i<N; i++) {
4124            final TaskRecord tr = mRecentTasks.get(i);
4125            if (task != tr) {
4126                if (task.userId != tr.userId) {
4127                    continue;
4128                }
4129                if (i > MAX_RECENT_BITMAPS) {
4130                    tr.freeLastThumbnail();
4131                }
4132                final Intent trIntent = tr.intent;
4133                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4134                    (intent == null || !intent.filterEquals(trIntent))) {
4135                    continue;
4136                }
4137                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4138                if (document && trIsDocument) {
4139                    // These are the same document activity (not necessarily the same doc).
4140                    if (maxRecents > 0) {
4141                        --maxRecents;
4142                        continue;
4143                    }
4144                    // Hit the maximum number of documents for this task. Fall through
4145                    // and remove this document from recents.
4146                } else if (document || trIsDocument) {
4147                    // Only one of these is a document. Not the droid we're looking for.
4148                    continue;
4149                }
4150            }
4151
4152            if (!doTrim) {
4153                // If the caller is not actually asking for a trim, just tell them we reached
4154                // a point where the trim would happen.
4155                return i;
4156            }
4157
4158            // Either task and tr are the same or, their affinities match or their intents match
4159            // and neither of them is a document, or they are documents using the same activity
4160            // and their maxRecents has been reached.
4161            tr.disposeThumbnail();
4162            mRecentTasks.remove(i);
4163            if (task != tr) {
4164                tr.removedFromRecents();
4165            }
4166            i--;
4167            N--;
4168            if (task.intent == null) {
4169                // If the new recent task we are adding is not fully
4170                // specified, then replace it with the existing recent task.
4171                task = tr;
4172            }
4173            notifyTaskPersisterLocked(tr, false);
4174        }
4175
4176        return -1;
4177    }
4178
4179    @Override
4180    public void reportActivityFullyDrawn(IBinder token) {
4181        synchronized (this) {
4182            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4183            if (r == null) {
4184                return;
4185            }
4186            r.reportFullyDrawnLocked();
4187        }
4188    }
4189
4190    @Override
4191    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192        synchronized (this) {
4193            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4194            if (r == null) {
4195                return;
4196            }
4197            final long origId = Binder.clearCallingIdentity();
4198            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4199            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4200                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4201            if (config != null) {
4202                r.frozenBeforeDestroy = true;
4203                if (!updateConfigurationLocked(config, r, false, false)) {
4204                    mStackSupervisor.resumeTopActivitiesLocked();
4205                }
4206            }
4207            Binder.restoreCallingIdentity(origId);
4208        }
4209    }
4210
4211    @Override
4212    public int getRequestedOrientation(IBinder token) {
4213        synchronized (this) {
4214            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4215            if (r == null) {
4216                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4217            }
4218            return mWindowManager.getAppOrientation(r.appToken);
4219        }
4220    }
4221
4222    /**
4223     * This is the internal entry point for handling Activity.finish().
4224     *
4225     * @param token The Binder token referencing the Activity we want to finish.
4226     * @param resultCode Result code, if any, from this Activity.
4227     * @param resultData Result data (Intent), if any, from this Activity.
4228     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4229     *            the root Activity in the task.
4230     *
4231     * @return Returns true if the activity successfully finished, or false if it is still running.
4232     */
4233    @Override
4234    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4235            boolean finishTask) {
4236        // Refuse possible leaked file descriptors
4237        if (resultData != null && resultData.hasFileDescriptors() == true) {
4238            throw new IllegalArgumentException("File descriptors passed in Intent");
4239        }
4240
4241        synchronized(this) {
4242            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4243            if (r == null) {
4244                return true;
4245            }
4246            // Keep track of the root activity of the task before we finish it
4247            TaskRecord tr = r.task;
4248            ActivityRecord rootR = tr.getRootActivity();
4249            if (rootR == null) {
4250                Slog.w(TAG, "Finishing task with all activities already finished");
4251            }
4252            // Do not allow task to finish in Lock Task mode.
4253            if (tr == mStackSupervisor.mLockTaskModeTask) {
4254                if (rootR == r) {
4255                    Slog.i(TAG, "Not finishing task in lock task mode");
4256                    mStackSupervisor.showLockTaskToast();
4257                    return false;
4258                }
4259            }
4260            if (mController != null) {
4261                // Find the first activity that is not finishing.
4262                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4263                if (next != null) {
4264                    // ask watcher if this is allowed
4265                    boolean resumeOK = true;
4266                    try {
4267                        resumeOK = mController.activityResuming(next.packageName);
4268                    } catch (RemoteException e) {
4269                        mController = null;
4270                        Watchdog.getInstance().setActivityController(null);
4271                    }
4272
4273                    if (!resumeOK) {
4274                        Slog.i(TAG, "Not finishing activity because controller resumed");
4275                        return false;
4276                    }
4277                }
4278            }
4279            final long origId = Binder.clearCallingIdentity();
4280            try {
4281                boolean res;
4282                if (finishTask && r == rootR) {
4283                    // If requested, remove the task that is associated to this activity only if it
4284                    // was the root activity in the task. The result code and data is ignored
4285                    // because we don't support returning them across task boundaries.
4286                    res = removeTaskByIdLocked(tr.taskId, false);
4287                    if (!res) {
4288                        Slog.i(TAG, "Removing task failed to finish activity");
4289                    }
4290                } else {
4291                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4292                            resultData, "app-request", true);
4293                    if (!res) {
4294                        Slog.i(TAG, "Failed to finish by app-request");
4295                    }
4296                }
4297                return res;
4298            } finally {
4299                Binder.restoreCallingIdentity(origId);
4300            }
4301        }
4302    }
4303
4304    @Override
4305    public final void finishHeavyWeightApp() {
4306        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4307                != PackageManager.PERMISSION_GRANTED) {
4308            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4309                    + Binder.getCallingPid()
4310                    + ", uid=" + Binder.getCallingUid()
4311                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4312            Slog.w(TAG, msg);
4313            throw new SecurityException(msg);
4314        }
4315
4316        synchronized(this) {
4317            if (mHeavyWeightProcess == null) {
4318                return;
4319            }
4320
4321            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4322                    mHeavyWeightProcess.activities);
4323            for (int i=0; i<activities.size(); i++) {
4324                ActivityRecord r = activities.get(i);
4325                if (!r.finishing) {
4326                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4327                            null, "finish-heavy", true);
4328                }
4329            }
4330
4331            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4332                    mHeavyWeightProcess.userId, 0));
4333            mHeavyWeightProcess = null;
4334        }
4335    }
4336
4337    @Override
4338    public void crashApplication(int uid, int initialPid, String packageName,
4339            String message) {
4340        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4341                != PackageManager.PERMISSION_GRANTED) {
4342            String msg = "Permission Denial: crashApplication() from pid="
4343                    + Binder.getCallingPid()
4344                    + ", uid=" + Binder.getCallingUid()
4345                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4346            Slog.w(TAG, msg);
4347            throw new SecurityException(msg);
4348        }
4349
4350        synchronized(this) {
4351            ProcessRecord proc = null;
4352
4353            // Figure out which process to kill.  We don't trust that initialPid
4354            // still has any relation to current pids, so must scan through the
4355            // list.
4356            synchronized (mPidsSelfLocked) {
4357                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4358                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4359                    if (p.uid != uid) {
4360                        continue;
4361                    }
4362                    if (p.pid == initialPid) {
4363                        proc = p;
4364                        break;
4365                    }
4366                    if (p.pkgList.containsKey(packageName)) {
4367                        proc = p;
4368                    }
4369                }
4370            }
4371
4372            if (proc == null) {
4373                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4374                        + " initialPid=" + initialPid
4375                        + " packageName=" + packageName);
4376                return;
4377            }
4378
4379            if (proc.thread != null) {
4380                if (proc.pid == Process.myPid()) {
4381                    Log.w(TAG, "crashApplication: trying to crash self!");
4382                    return;
4383                }
4384                long ident = Binder.clearCallingIdentity();
4385                try {
4386                    proc.thread.scheduleCrash(message);
4387                } catch (RemoteException e) {
4388                }
4389                Binder.restoreCallingIdentity(ident);
4390            }
4391        }
4392    }
4393
4394    @Override
4395    public final void finishSubActivity(IBinder token, String resultWho,
4396            int requestCode) {
4397        synchronized(this) {
4398            final long origId = Binder.clearCallingIdentity();
4399            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4400            if (r != null) {
4401                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4402            }
4403            Binder.restoreCallingIdentity(origId);
4404        }
4405    }
4406
4407    @Override
4408    public boolean finishActivityAffinity(IBinder token) {
4409        synchronized(this) {
4410            final long origId = Binder.clearCallingIdentity();
4411            try {
4412                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4413
4414                ActivityRecord rootR = r.task.getRootActivity();
4415                // Do not allow task to finish in Lock Task mode.
4416                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4417                    if (rootR == r) {
4418                        mStackSupervisor.showLockTaskToast();
4419                        return false;
4420                    }
4421                }
4422                boolean res = false;
4423                if (r != null) {
4424                    res = r.task.stack.finishActivityAffinityLocked(r);
4425                }
4426                return res;
4427            } finally {
4428                Binder.restoreCallingIdentity(origId);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public void finishVoiceTask(IVoiceInteractionSession session) {
4435        synchronized(this) {
4436            final long origId = Binder.clearCallingIdentity();
4437            try {
4438                mStackSupervisor.finishVoiceTask(session);
4439            } finally {
4440                Binder.restoreCallingIdentity(origId);
4441            }
4442        }
4443
4444    }
4445
4446    @Override
4447    public boolean releaseActivityInstance(IBinder token) {
4448        synchronized(this) {
4449            final long origId = Binder.clearCallingIdentity();
4450            try {
4451                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4452                if (r.task == null || r.task.stack == null) {
4453                    return false;
4454                }
4455                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4456            } finally {
4457                Binder.restoreCallingIdentity(origId);
4458            }
4459        }
4460    }
4461
4462    @Override
4463    public void releaseSomeActivities(IApplicationThread appInt) {
4464        synchronized(this) {
4465            final long origId = Binder.clearCallingIdentity();
4466            try {
4467                ProcessRecord app = getRecordForAppLocked(appInt);
4468                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4469            } finally {
4470                Binder.restoreCallingIdentity(origId);
4471            }
4472        }
4473    }
4474
4475    @Override
4476    public boolean willActivityBeVisible(IBinder token) {
4477        synchronized(this) {
4478            ActivityStack stack = ActivityRecord.getStackLocked(token);
4479            if (stack != null) {
4480                return stack.willActivityBeVisibleLocked(token);
4481            }
4482            return false;
4483        }
4484    }
4485
4486    @Override
4487    public void overridePendingTransition(IBinder token, String packageName,
4488            int enterAnim, int exitAnim) {
4489        synchronized(this) {
4490            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4491            if (self == null) {
4492                return;
4493            }
4494
4495            final long origId = Binder.clearCallingIdentity();
4496
4497            if (self.state == ActivityState.RESUMED
4498                    || self.state == ActivityState.PAUSING) {
4499                mWindowManager.overridePendingAppTransition(packageName,
4500                        enterAnim, exitAnim, null);
4501            }
4502
4503            Binder.restoreCallingIdentity(origId);
4504        }
4505    }
4506
4507    /**
4508     * Main function for removing an existing process from the activity manager
4509     * as a result of that process going away.  Clears out all connections
4510     * to the process.
4511     */
4512    private final void handleAppDiedLocked(ProcessRecord app,
4513            boolean restarting, boolean allowRestart) {
4514        int pid = app.pid;
4515        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4516        if (!kept && !restarting) {
4517            removeLruProcessLocked(app);
4518            if (pid > 0) {
4519                ProcessList.remove(pid);
4520            }
4521        }
4522
4523        if (mProfileProc == app) {
4524            clearProfilerLocked();
4525        }
4526
4527        // Remove this application's activities from active lists.
4528        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4529
4530        app.activities.clear();
4531
4532        if (app.instrumentationClass != null) {
4533            Slog.w(TAG, "Crash of app " + app.processName
4534                  + " running instrumentation " + app.instrumentationClass);
4535            Bundle info = new Bundle();
4536            info.putString("shortMsg", "Process crashed.");
4537            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4538        }
4539
4540        if (!restarting) {
4541            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4542                // If there was nothing to resume, and we are not already
4543                // restarting this process, but there is a visible activity that
4544                // is hosted by the process...  then make sure all visible
4545                // activities are running, taking care of restarting this
4546                // process.
4547                if (hasVisibleActivities) {
4548                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4549                }
4550            }
4551        }
4552    }
4553
4554    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4555        IBinder threadBinder = thread.asBinder();
4556        // Find the application record.
4557        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4558            ProcessRecord rec = mLruProcesses.get(i);
4559            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4560                return i;
4561            }
4562        }
4563        return -1;
4564    }
4565
4566    final ProcessRecord getRecordForAppLocked(
4567            IApplicationThread thread) {
4568        if (thread == null) {
4569            return null;
4570        }
4571
4572        int appIndex = getLRURecordIndexForAppLocked(thread);
4573        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4574    }
4575
4576    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4577        // If there are no longer any background processes running,
4578        // and the app that died was not running instrumentation,
4579        // then tell everyone we are now low on memory.
4580        boolean haveBg = false;
4581        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4582            ProcessRecord rec = mLruProcesses.get(i);
4583            if (rec.thread != null
4584                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4585                haveBg = true;
4586                break;
4587            }
4588        }
4589
4590        if (!haveBg) {
4591            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4592            if (doReport) {
4593                long now = SystemClock.uptimeMillis();
4594                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4595                    doReport = false;
4596                } else {
4597                    mLastMemUsageReportTime = now;
4598                }
4599            }
4600            final ArrayList<ProcessMemInfo> memInfos
4601                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4602            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4603            long now = SystemClock.uptimeMillis();
4604            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4605                ProcessRecord rec = mLruProcesses.get(i);
4606                if (rec == dyingProc || rec.thread == null) {
4607                    continue;
4608                }
4609                if (doReport) {
4610                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4611                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4612                }
4613                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4614                    // The low memory report is overriding any current
4615                    // state for a GC request.  Make sure to do
4616                    // heavy/important/visible/foreground processes first.
4617                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4618                        rec.lastRequestedGc = 0;
4619                    } else {
4620                        rec.lastRequestedGc = rec.lastLowMemory;
4621                    }
4622                    rec.reportLowMemory = true;
4623                    rec.lastLowMemory = now;
4624                    mProcessesToGc.remove(rec);
4625                    addProcessToGcListLocked(rec);
4626                }
4627            }
4628            if (doReport) {
4629                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4630                mHandler.sendMessage(msg);
4631            }
4632            scheduleAppGcsLocked();
4633        }
4634    }
4635
4636    final void appDiedLocked(ProcessRecord app) {
4637       appDiedLocked(app, app.pid, app.thread);
4638    }
4639
4640    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4641        // First check if this ProcessRecord is actually active for the pid.
4642        synchronized (mPidsSelfLocked) {
4643            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4644            if (curProc != app) {
4645                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4646                return;
4647            }
4648        }
4649
4650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4651        synchronized (stats) {
4652            stats.noteProcessDiedLocked(app.info.uid, pid);
4653        }
4654
4655        Process.killProcessQuiet(pid);
4656        Process.killProcessGroup(app.info.uid, pid);
4657        app.killed = true;
4658
4659        // Clean up already done if the process has been re-started.
4660        if (app.pid == pid && app.thread != null &&
4661                app.thread.asBinder() == thread.asBinder()) {
4662            boolean doLowMem = app.instrumentationClass == null;
4663            boolean doOomAdj = doLowMem;
4664            if (!app.killedByAm) {
4665                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4666                        + ") has died");
4667                mAllowLowerMemLevel = true;
4668            } else {
4669                // Note that we always want to do oom adj to update our state with the
4670                // new number of procs.
4671                mAllowLowerMemLevel = false;
4672                doLowMem = false;
4673            }
4674            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4675            if (DEBUG_CLEANUP) Slog.v(
4676                TAG, "Dying app: " + app + ", pid: " + pid
4677                + ", thread: " + thread.asBinder());
4678            handleAppDiedLocked(app, false, true);
4679
4680            if (doOomAdj) {
4681                updateOomAdjLocked();
4682            }
4683            if (doLowMem) {
4684                doLowMemReportIfNeededLocked(app);
4685            }
4686        } else if (app.pid != pid) {
4687            // A new process has already been started.
4688            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4689                    + ") has died and restarted (pid " + app.pid + ").");
4690            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4691        } else if (DEBUG_PROCESSES) {
4692            Slog.d(TAG, "Received spurious death notification for thread "
4693                    + thread.asBinder());
4694        }
4695    }
4696
4697    /**
4698     * If a stack trace dump file is configured, dump process stack traces.
4699     * @param clearTraces causes the dump file to be erased prior to the new
4700     *    traces being written, if true; when false, the new traces will be
4701     *    appended to any existing file content.
4702     * @param firstPids of dalvik VM processes to dump stack traces for first
4703     * @param lastPids of dalvik VM processes to dump stack traces for last
4704     * @param nativeProcs optional list of native process names to dump stack crawls
4705     * @return file containing stack traces, or null if no dump file is configured
4706     */
4707    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4708            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4709        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4710        if (tracesPath == null || tracesPath.length() == 0) {
4711            return null;
4712        }
4713
4714        File tracesFile = new File(tracesPath);
4715        try {
4716            File tracesDir = tracesFile.getParentFile();
4717            if (!tracesDir.exists()) {
4718                tracesDir.mkdirs();
4719                if (!SELinux.restorecon(tracesDir)) {
4720                    return null;
4721                }
4722            }
4723            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4724
4725            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4726            tracesFile.createNewFile();
4727            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4728        } catch (IOException e) {
4729            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4730            return null;
4731        }
4732
4733        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4734        return tracesFile;
4735    }
4736
4737    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4738            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4739        // Use a FileObserver to detect when traces finish writing.
4740        // The order of traces is considered important to maintain for legibility.
4741        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4742            @Override
4743            public synchronized void onEvent(int event, String path) { notify(); }
4744        };
4745
4746        try {
4747            observer.startWatching();
4748
4749            // First collect all of the stacks of the most important pids.
4750            if (firstPids != null) {
4751                try {
4752                    int num = firstPids.size();
4753                    for (int i = 0; i < num; i++) {
4754                        synchronized (observer) {
4755                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4756                            observer.wait(200);  // Wait for write-close, give up after 200msec
4757                        }
4758                    }
4759                } catch (InterruptedException e) {
4760                    Slog.wtf(TAG, e);
4761                }
4762            }
4763
4764            // Next collect the stacks of the native pids
4765            if (nativeProcs != null) {
4766                int[] pids = Process.getPidsForCommands(nativeProcs);
4767                if (pids != null) {
4768                    for (int pid : pids) {
4769                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4770                    }
4771                }
4772            }
4773
4774            // Lastly, measure CPU usage.
4775            if (processCpuTracker != null) {
4776                processCpuTracker.init();
4777                System.gc();
4778                processCpuTracker.update();
4779                try {
4780                    synchronized (processCpuTracker) {
4781                        processCpuTracker.wait(500); // measure over 1/2 second.
4782                    }
4783                } catch (InterruptedException e) {
4784                }
4785                processCpuTracker.update();
4786
4787                // We'll take the stack crawls of just the top apps using CPU.
4788                final int N = processCpuTracker.countWorkingStats();
4789                int numProcs = 0;
4790                for (int i=0; i<N && numProcs<5; i++) {
4791                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4792                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4793                        numProcs++;
4794                        try {
4795                            synchronized (observer) {
4796                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4797                                observer.wait(200);  // Wait for write-close, give up after 200msec
4798                            }
4799                        } catch (InterruptedException e) {
4800                            Slog.wtf(TAG, e);
4801                        }
4802
4803                    }
4804                }
4805            }
4806        } finally {
4807            observer.stopWatching();
4808        }
4809    }
4810
4811    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4812        if (true || IS_USER_BUILD) {
4813            return;
4814        }
4815        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4816        if (tracesPath == null || tracesPath.length() == 0) {
4817            return;
4818        }
4819
4820        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4821        StrictMode.allowThreadDiskWrites();
4822        try {
4823            final File tracesFile = new File(tracesPath);
4824            final File tracesDir = tracesFile.getParentFile();
4825            final File tracesTmp = new File(tracesDir, "__tmp__");
4826            try {
4827                if (!tracesDir.exists()) {
4828                    tracesDir.mkdirs();
4829                    if (!SELinux.restorecon(tracesDir.getPath())) {
4830                        return;
4831                    }
4832                }
4833                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4834
4835                if (tracesFile.exists()) {
4836                    tracesTmp.delete();
4837                    tracesFile.renameTo(tracesTmp);
4838                }
4839                StringBuilder sb = new StringBuilder();
4840                Time tobj = new Time();
4841                tobj.set(System.currentTimeMillis());
4842                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4843                sb.append(": ");
4844                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4845                sb.append(" since ");
4846                sb.append(msg);
4847                FileOutputStream fos = new FileOutputStream(tracesFile);
4848                fos.write(sb.toString().getBytes());
4849                if (app == null) {
4850                    fos.write("\n*** No application process!".getBytes());
4851                }
4852                fos.close();
4853                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4854            } catch (IOException e) {
4855                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4856                return;
4857            }
4858
4859            if (app != null) {
4860                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4861                firstPids.add(app.pid);
4862                dumpStackTraces(tracesPath, firstPids, null, null, null);
4863            }
4864
4865            File lastTracesFile = null;
4866            File curTracesFile = null;
4867            for (int i=9; i>=0; i--) {
4868                String name = String.format(Locale.US, "slow%02d.txt", i);
4869                curTracesFile = new File(tracesDir, name);
4870                if (curTracesFile.exists()) {
4871                    if (lastTracesFile != null) {
4872                        curTracesFile.renameTo(lastTracesFile);
4873                    } else {
4874                        curTracesFile.delete();
4875                    }
4876                }
4877                lastTracesFile = curTracesFile;
4878            }
4879            tracesFile.renameTo(curTracesFile);
4880            if (tracesTmp.exists()) {
4881                tracesTmp.renameTo(tracesFile);
4882            }
4883        } finally {
4884            StrictMode.setThreadPolicy(oldPolicy);
4885        }
4886    }
4887
4888    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4889            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4890        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4891        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4892
4893        if (mController != null) {
4894            try {
4895                // 0 == continue, -1 = kill process immediately
4896                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4897                if (res < 0 && app.pid != MY_PID) {
4898                    app.kill("anr", true);
4899                }
4900            } catch (RemoteException e) {
4901                mController = null;
4902                Watchdog.getInstance().setActivityController(null);
4903            }
4904        }
4905
4906        long anrTime = SystemClock.uptimeMillis();
4907        if (MONITOR_CPU_USAGE) {
4908            updateCpuStatsNow();
4909        }
4910
4911        synchronized (this) {
4912            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4913            if (mShuttingDown) {
4914                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4915                return;
4916            } else if (app.notResponding) {
4917                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4918                return;
4919            } else if (app.crashing) {
4920                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4921                return;
4922            }
4923
4924            // In case we come through here for the same app before completing
4925            // this one, mark as anring now so we will bail out.
4926            app.notResponding = true;
4927
4928            // Log the ANR to the event log.
4929            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4930                    app.processName, app.info.flags, annotation);
4931
4932            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4933            firstPids.add(app.pid);
4934
4935            int parentPid = app.pid;
4936            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4937            if (parentPid != app.pid) firstPids.add(parentPid);
4938
4939            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4940
4941            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4942                ProcessRecord r = mLruProcesses.get(i);
4943                if (r != null && r.thread != null) {
4944                    int pid = r.pid;
4945                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4946                        if (r.persistent) {
4947                            firstPids.add(pid);
4948                        } else {
4949                            lastPids.put(pid, Boolean.TRUE);
4950                        }
4951                    }
4952                }
4953            }
4954        }
4955
4956        // Log the ANR to the main log.
4957        StringBuilder info = new StringBuilder();
4958        info.setLength(0);
4959        info.append("ANR in ").append(app.processName);
4960        if (activity != null && activity.shortComponentName != null) {
4961            info.append(" (").append(activity.shortComponentName).append(")");
4962        }
4963        info.append("\n");
4964        info.append("PID: ").append(app.pid).append("\n");
4965        if (annotation != null) {
4966            info.append("Reason: ").append(annotation).append("\n");
4967        }
4968        if (parent != null && parent != activity) {
4969            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4970        }
4971
4972        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4973
4974        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4975                NATIVE_STACKS_OF_INTEREST);
4976
4977        String cpuInfo = null;
4978        if (MONITOR_CPU_USAGE) {
4979            updateCpuStatsNow();
4980            synchronized (mProcessCpuTracker) {
4981                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4982            }
4983            info.append(processCpuTracker.printCurrentLoad());
4984            info.append(cpuInfo);
4985        }
4986
4987        info.append(processCpuTracker.printCurrentState(anrTime));
4988
4989        Slog.e(TAG, info.toString());
4990        if (tracesFile == null) {
4991            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4992            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4993        }
4994
4995        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4996                cpuInfo, tracesFile, null);
4997
4998        if (mController != null) {
4999            try {
5000                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5001                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5002                if (res != 0) {
5003                    if (res < 0 && app.pid != MY_PID) {
5004                        app.kill("anr", true);
5005                    } else {
5006                        synchronized (this) {
5007                            mServices.scheduleServiceTimeoutLocked(app);
5008                        }
5009                    }
5010                    return;
5011                }
5012            } catch (RemoteException e) {
5013                mController = null;
5014                Watchdog.getInstance().setActivityController(null);
5015            }
5016        }
5017
5018        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5019        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5020                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5021
5022        synchronized (this) {
5023            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5024                app.kill("bg anr", true);
5025                return;
5026            }
5027
5028            // Set the app's notResponding state, and look up the errorReportReceiver
5029            makeAppNotRespondingLocked(app,
5030                    activity != null ? activity.shortComponentName : null,
5031                    annotation != null ? "ANR " + annotation : "ANR",
5032                    info.toString());
5033
5034            // Bring up the infamous App Not Responding dialog
5035            Message msg = Message.obtain();
5036            HashMap<String, Object> map = new HashMap<String, Object>();
5037            msg.what = SHOW_NOT_RESPONDING_MSG;
5038            msg.obj = map;
5039            msg.arg1 = aboveSystem ? 1 : 0;
5040            map.put("app", app);
5041            if (activity != null) {
5042                map.put("activity", activity);
5043            }
5044
5045            mHandler.sendMessage(msg);
5046        }
5047    }
5048
5049    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5050        if (!mLaunchWarningShown) {
5051            mLaunchWarningShown = true;
5052            mHandler.post(new Runnable() {
5053                @Override
5054                public void run() {
5055                    synchronized (ActivityManagerService.this) {
5056                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5057                        d.show();
5058                        mHandler.postDelayed(new Runnable() {
5059                            @Override
5060                            public void run() {
5061                                synchronized (ActivityManagerService.this) {
5062                                    d.dismiss();
5063                                    mLaunchWarningShown = false;
5064                                }
5065                            }
5066                        }, 4000);
5067                    }
5068                }
5069            });
5070        }
5071    }
5072
5073    @Override
5074    public boolean clearApplicationUserData(final String packageName,
5075            final IPackageDataObserver observer, int userId) {
5076        enforceNotIsolatedCaller("clearApplicationUserData");
5077        int uid = Binder.getCallingUid();
5078        int pid = Binder.getCallingPid();
5079        userId = handleIncomingUser(pid, uid,
5080                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5081        long callingId = Binder.clearCallingIdentity();
5082        try {
5083            IPackageManager pm = AppGlobals.getPackageManager();
5084            int pkgUid = -1;
5085            synchronized(this) {
5086                try {
5087                    pkgUid = pm.getPackageUid(packageName, userId);
5088                } catch (RemoteException e) {
5089                }
5090                if (pkgUid == -1) {
5091                    Slog.w(TAG, "Invalid packageName: " + packageName);
5092                    if (observer != null) {
5093                        try {
5094                            observer.onRemoveCompleted(packageName, false);
5095                        } catch (RemoteException e) {
5096                            Slog.i(TAG, "Observer no longer exists.");
5097                        }
5098                    }
5099                    return false;
5100                }
5101                if (uid == pkgUid || checkComponentPermission(
5102                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5103                        pid, uid, -1, true)
5104                        == PackageManager.PERMISSION_GRANTED) {
5105                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5106                } else {
5107                    throw new SecurityException("PID " + pid + " does not have permission "
5108                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5109                                    + " of package " + packageName);
5110                }
5111
5112                // Remove all tasks match the cleared application package and user
5113                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5114                    final TaskRecord tr = mRecentTasks.get(i);
5115                    final String taskPackageName =
5116                            tr.getBaseIntent().getComponent().getPackageName();
5117                    if (tr.userId != userId) continue;
5118                    if (!taskPackageName.equals(packageName)) continue;
5119                    removeTaskByIdLocked(tr.taskId, false);
5120                }
5121            }
5122
5123            try {
5124                // Clear application user data
5125                pm.clearApplicationUserData(packageName, observer, userId);
5126
5127                synchronized(this) {
5128                    // Remove all permissions granted from/to this package
5129                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5130                }
5131
5132                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5133                        Uri.fromParts("package", packageName, null));
5134                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5135                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5136                        null, null, 0, null, null, null, false, false, userId);
5137            } catch (RemoteException e) {
5138            }
5139        } finally {
5140            Binder.restoreCallingIdentity(callingId);
5141        }
5142        return true;
5143    }
5144
5145    @Override
5146    public void killBackgroundProcesses(final String packageName, int userId) {
5147        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5148                != PackageManager.PERMISSION_GRANTED &&
5149                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5150                        != PackageManager.PERMISSION_GRANTED) {
5151            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5152                    + Binder.getCallingPid()
5153                    + ", uid=" + Binder.getCallingUid()
5154                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5155            Slog.w(TAG, msg);
5156            throw new SecurityException(msg);
5157        }
5158
5159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5160                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5161        long callingId = Binder.clearCallingIdentity();
5162        try {
5163            IPackageManager pm = AppGlobals.getPackageManager();
5164            synchronized(this) {
5165                int appId = -1;
5166                try {
5167                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5168                } catch (RemoteException e) {
5169                }
5170                if (appId == -1) {
5171                    Slog.w(TAG, "Invalid packageName: " + packageName);
5172                    return;
5173                }
5174                killPackageProcessesLocked(packageName, appId, userId,
5175                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5176            }
5177        } finally {
5178            Binder.restoreCallingIdentity(callingId);
5179        }
5180    }
5181
5182    @Override
5183    public void killAllBackgroundProcesses() {
5184        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5185                != PackageManager.PERMISSION_GRANTED) {
5186            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5187                    + Binder.getCallingPid()
5188                    + ", uid=" + Binder.getCallingUid()
5189                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5190            Slog.w(TAG, msg);
5191            throw new SecurityException(msg);
5192        }
5193
5194        long callingId = Binder.clearCallingIdentity();
5195        try {
5196            synchronized(this) {
5197                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5198                final int NP = mProcessNames.getMap().size();
5199                for (int ip=0; ip<NP; ip++) {
5200                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5201                    final int NA = apps.size();
5202                    for (int ia=0; ia<NA; ia++) {
5203                        ProcessRecord app = apps.valueAt(ia);
5204                        if (app.persistent) {
5205                            // we don't kill persistent processes
5206                            continue;
5207                        }
5208                        if (app.removed) {
5209                            procs.add(app);
5210                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5211                            app.removed = true;
5212                            procs.add(app);
5213                        }
5214                    }
5215                }
5216
5217                int N = procs.size();
5218                for (int i=0; i<N; i++) {
5219                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5220                }
5221                mAllowLowerMemLevel = true;
5222                updateOomAdjLocked();
5223                doLowMemReportIfNeededLocked(null);
5224            }
5225        } finally {
5226            Binder.restoreCallingIdentity(callingId);
5227        }
5228    }
5229
5230    @Override
5231    public void forceStopPackage(final String packageName, int userId) {
5232        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5233                != PackageManager.PERMISSION_GRANTED) {
5234            String msg = "Permission Denial: forceStopPackage() from pid="
5235                    + Binder.getCallingPid()
5236                    + ", uid=" + Binder.getCallingUid()
5237                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5238            Slog.w(TAG, msg);
5239            throw new SecurityException(msg);
5240        }
5241        final int callingPid = Binder.getCallingPid();
5242        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5243                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5244        long callingId = Binder.clearCallingIdentity();
5245        try {
5246            IPackageManager pm = AppGlobals.getPackageManager();
5247            synchronized(this) {
5248                int[] users = userId == UserHandle.USER_ALL
5249                        ? getUsersLocked() : new int[] { userId };
5250                for (int user : users) {
5251                    int pkgUid = -1;
5252                    try {
5253                        pkgUid = pm.getPackageUid(packageName, user);
5254                    } catch (RemoteException e) {
5255                    }
5256                    if (pkgUid == -1) {
5257                        Slog.w(TAG, "Invalid packageName: " + packageName);
5258                        continue;
5259                    }
5260                    try {
5261                        pm.setPackageStoppedState(packageName, true, user);
5262                    } catch (RemoteException e) {
5263                    } catch (IllegalArgumentException e) {
5264                        Slog.w(TAG, "Failed trying to unstop package "
5265                                + packageName + ": " + e);
5266                    }
5267                    if (isUserRunningLocked(user, false)) {
5268                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5269                    }
5270                }
5271            }
5272        } finally {
5273            Binder.restoreCallingIdentity(callingId);
5274        }
5275    }
5276
5277    @Override
5278    public void addPackageDependency(String packageName) {
5279        synchronized (this) {
5280            int callingPid = Binder.getCallingPid();
5281            if (callingPid == Process.myPid()) {
5282                //  Yeah, um, no.
5283                Slog.w(TAG, "Can't addPackageDependency on system process");
5284                return;
5285            }
5286            ProcessRecord proc;
5287            synchronized (mPidsSelfLocked) {
5288                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5289            }
5290            if (proc != null) {
5291                if (proc.pkgDeps == null) {
5292                    proc.pkgDeps = new ArraySet<String>(1);
5293                }
5294                proc.pkgDeps.add(packageName);
5295            }
5296        }
5297    }
5298
5299    /*
5300     * The pkg name and app id have to be specified.
5301     */
5302    @Override
5303    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5304        if (pkg == null) {
5305            return;
5306        }
5307        // Make sure the uid is valid.
5308        if (appid < 0) {
5309            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5310            return;
5311        }
5312        int callerUid = Binder.getCallingUid();
5313        // Only the system server can kill an application
5314        if (callerUid == Process.SYSTEM_UID) {
5315            // Post an aysnc message to kill the application
5316            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5317            msg.arg1 = appid;
5318            msg.arg2 = 0;
5319            Bundle bundle = new Bundle();
5320            bundle.putString("pkg", pkg);
5321            bundle.putString("reason", reason);
5322            msg.obj = bundle;
5323            mHandler.sendMessage(msg);
5324        } else {
5325            throw new SecurityException(callerUid + " cannot kill pkg: " +
5326                    pkg);
5327        }
5328    }
5329
5330    @Override
5331    public void closeSystemDialogs(String reason) {
5332        enforceNotIsolatedCaller("closeSystemDialogs");
5333
5334        final int pid = Binder.getCallingPid();
5335        final int uid = Binder.getCallingUid();
5336        final long origId = Binder.clearCallingIdentity();
5337        try {
5338            synchronized (this) {
5339                // Only allow this from foreground processes, so that background
5340                // applications can't abuse it to prevent system UI from being shown.
5341                if (uid >= Process.FIRST_APPLICATION_UID) {
5342                    ProcessRecord proc;
5343                    synchronized (mPidsSelfLocked) {
5344                        proc = mPidsSelfLocked.get(pid);
5345                    }
5346                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5347                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5348                                + " from background process " + proc);
5349                        return;
5350                    }
5351                }
5352                closeSystemDialogsLocked(reason);
5353            }
5354        } finally {
5355            Binder.restoreCallingIdentity(origId);
5356        }
5357    }
5358
5359    void closeSystemDialogsLocked(String reason) {
5360        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5361        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5362                | Intent.FLAG_RECEIVER_FOREGROUND);
5363        if (reason != null) {
5364            intent.putExtra("reason", reason);
5365        }
5366        mWindowManager.closeSystemDialogs(reason);
5367
5368        mStackSupervisor.closeSystemDialogsLocked();
5369
5370        broadcastIntentLocked(null, null, intent, null,
5371                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5372                Process.SYSTEM_UID, UserHandle.USER_ALL);
5373    }
5374
5375    @Override
5376    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5377        enforceNotIsolatedCaller("getProcessMemoryInfo");
5378        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5379        for (int i=pids.length-1; i>=0; i--) {
5380            ProcessRecord proc;
5381            int oomAdj;
5382            synchronized (this) {
5383                synchronized (mPidsSelfLocked) {
5384                    proc = mPidsSelfLocked.get(pids[i]);
5385                    oomAdj = proc != null ? proc.setAdj : 0;
5386                }
5387            }
5388            infos[i] = new Debug.MemoryInfo();
5389            Debug.getMemoryInfo(pids[i], infos[i]);
5390            if (proc != null) {
5391                synchronized (this) {
5392                    if (proc.thread != null && proc.setAdj == oomAdj) {
5393                        // Record this for posterity if the process has been stable.
5394                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5395                                infos[i].getTotalUss(), false, proc.pkgList);
5396                    }
5397                }
5398            }
5399        }
5400        return infos;
5401    }
5402
5403    @Override
5404    public long[] getProcessPss(int[] pids) {
5405        enforceNotIsolatedCaller("getProcessPss");
5406        long[] pss = new long[pids.length];
5407        for (int i=pids.length-1; i>=0; i--) {
5408            ProcessRecord proc;
5409            int oomAdj;
5410            synchronized (this) {
5411                synchronized (mPidsSelfLocked) {
5412                    proc = mPidsSelfLocked.get(pids[i]);
5413                    oomAdj = proc != null ? proc.setAdj : 0;
5414                }
5415            }
5416            long[] tmpUss = new long[1];
5417            pss[i] = Debug.getPss(pids[i], tmpUss);
5418            if (proc != null) {
5419                synchronized (this) {
5420                    if (proc.thread != null && proc.setAdj == oomAdj) {
5421                        // Record this for posterity if the process has been stable.
5422                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5423                    }
5424                }
5425            }
5426        }
5427        return pss;
5428    }
5429
5430    @Override
5431    public void killApplicationProcess(String processName, int uid) {
5432        if (processName == null) {
5433            return;
5434        }
5435
5436        int callerUid = Binder.getCallingUid();
5437        // Only the system server can kill an application
5438        if (callerUid == Process.SYSTEM_UID) {
5439            synchronized (this) {
5440                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5441                if (app != null && app.thread != null) {
5442                    try {
5443                        app.thread.scheduleSuicide();
5444                    } catch (RemoteException e) {
5445                        // If the other end already died, then our work here is done.
5446                    }
5447                } else {
5448                    Slog.w(TAG, "Process/uid not found attempting kill of "
5449                            + processName + " / " + uid);
5450                }
5451            }
5452        } else {
5453            throw new SecurityException(callerUid + " cannot kill app process: " +
5454                    processName);
5455        }
5456    }
5457
5458    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5459        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5460                false, true, false, false, UserHandle.getUserId(uid), reason);
5461        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5462                Uri.fromParts("package", packageName, null));
5463        if (!mProcessesReady) {
5464            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5465                    | Intent.FLAG_RECEIVER_FOREGROUND);
5466        }
5467        intent.putExtra(Intent.EXTRA_UID, uid);
5468        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5469        broadcastIntentLocked(null, null, intent,
5470                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5471                false, false,
5472                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5473    }
5474
5475    private void forceStopUserLocked(int userId, String reason) {
5476        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5477        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5478        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5479                | Intent.FLAG_RECEIVER_FOREGROUND);
5480        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5481        broadcastIntentLocked(null, null, intent,
5482                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5483                false, false,
5484                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5485    }
5486
5487    private final boolean killPackageProcessesLocked(String packageName, int appId,
5488            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5489            boolean doit, boolean evenPersistent, String reason) {
5490        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5491
5492        // Remove all processes this package may have touched: all with the
5493        // same UID (except for the system or root user), and all whose name
5494        // matches the package name.
5495        final int NP = mProcessNames.getMap().size();
5496        for (int ip=0; ip<NP; ip++) {
5497            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5498            final int NA = apps.size();
5499            for (int ia=0; ia<NA; ia++) {
5500                ProcessRecord app = apps.valueAt(ia);
5501                if (app.persistent && !evenPersistent) {
5502                    // we don't kill persistent processes
5503                    continue;
5504                }
5505                if (app.removed) {
5506                    if (doit) {
5507                        procs.add(app);
5508                    }
5509                    continue;
5510                }
5511
5512                // Skip process if it doesn't meet our oom adj requirement.
5513                if (app.setAdj < minOomAdj) {
5514                    continue;
5515                }
5516
5517                // If no package is specified, we call all processes under the
5518                // give user id.
5519                if (packageName == null) {
5520                    if (app.userId != userId) {
5521                        continue;
5522                    }
5523                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5524                        continue;
5525                    }
5526                // Package has been specified, we want to hit all processes
5527                // that match it.  We need to qualify this by the processes
5528                // that are running under the specified app and user ID.
5529                } else {
5530                    final boolean isDep = app.pkgDeps != null
5531                            && app.pkgDeps.contains(packageName);
5532                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5533                        continue;
5534                    }
5535                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5536                        continue;
5537                    }
5538                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5539                        continue;
5540                    }
5541                }
5542
5543                // Process has passed all conditions, kill it!
5544                if (!doit) {
5545                    return true;
5546                }
5547                app.removed = true;
5548                procs.add(app);
5549            }
5550        }
5551
5552        int N = procs.size();
5553        for (int i=0; i<N; i++) {
5554            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5555        }
5556        updateOomAdjLocked();
5557        return N > 0;
5558    }
5559
5560    private final boolean forceStopPackageLocked(String name, int appId,
5561            boolean callerWillRestart, boolean purgeCache, boolean doit,
5562            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5563        int i;
5564        int N;
5565
5566        if (userId == UserHandle.USER_ALL && name == null) {
5567            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5568        }
5569
5570        if (appId < 0 && name != null) {
5571            try {
5572                appId = UserHandle.getAppId(
5573                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5574            } catch (RemoteException e) {
5575            }
5576        }
5577
5578        if (doit) {
5579            if (name != null) {
5580                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5581                        + " user=" + userId + ": " + reason);
5582            } else {
5583                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5584            }
5585
5586            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5587            for (int ip=pmap.size()-1; ip>=0; ip--) {
5588                SparseArray<Long> ba = pmap.valueAt(ip);
5589                for (i=ba.size()-1; i>=0; i--) {
5590                    boolean remove = false;
5591                    final int entUid = ba.keyAt(i);
5592                    if (name != null) {
5593                        if (userId == UserHandle.USER_ALL) {
5594                            if (UserHandle.getAppId(entUid) == appId) {
5595                                remove = true;
5596                            }
5597                        } else {
5598                            if (entUid == UserHandle.getUid(userId, appId)) {
5599                                remove = true;
5600                            }
5601                        }
5602                    } else if (UserHandle.getUserId(entUid) == userId) {
5603                        remove = true;
5604                    }
5605                    if (remove) {
5606                        ba.removeAt(i);
5607                    }
5608                }
5609                if (ba.size() == 0) {
5610                    pmap.removeAt(ip);
5611                }
5612            }
5613        }
5614
5615        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5616                -100, callerWillRestart, true, doit, evenPersistent,
5617                name == null ? ("stop user " + userId) : ("stop " + name));
5618
5619        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5620            if (!doit) {
5621                return true;
5622            }
5623            didSomething = true;
5624        }
5625
5626        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5627            if (!doit) {
5628                return true;
5629            }
5630            didSomething = true;
5631        }
5632
5633        if (name == null) {
5634            // Remove all sticky broadcasts from this user.
5635            mStickyBroadcasts.remove(userId);
5636        }
5637
5638        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5639        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5640                userId, providers)) {
5641            if (!doit) {
5642                return true;
5643            }
5644            didSomething = true;
5645        }
5646        N = providers.size();
5647        for (i=0; i<N; i++) {
5648            removeDyingProviderLocked(null, providers.get(i), true);
5649        }
5650
5651        // Remove transient permissions granted from/to this package/user
5652        removeUriPermissionsForPackageLocked(name, userId, false);
5653
5654        if (name == null || uninstalling) {
5655            // Remove pending intents.  For now we only do this when force
5656            // stopping users, because we have some problems when doing this
5657            // for packages -- app widgets are not currently cleaned up for
5658            // such packages, so they can be left with bad pending intents.
5659            if (mIntentSenderRecords.size() > 0) {
5660                Iterator<WeakReference<PendingIntentRecord>> it
5661                        = mIntentSenderRecords.values().iterator();
5662                while (it.hasNext()) {
5663                    WeakReference<PendingIntentRecord> wpir = it.next();
5664                    if (wpir == null) {
5665                        it.remove();
5666                        continue;
5667                    }
5668                    PendingIntentRecord pir = wpir.get();
5669                    if (pir == null) {
5670                        it.remove();
5671                        continue;
5672                    }
5673                    if (name == null) {
5674                        // Stopping user, remove all objects for the user.
5675                        if (pir.key.userId != userId) {
5676                            // Not the same user, skip it.
5677                            continue;
5678                        }
5679                    } else {
5680                        if (UserHandle.getAppId(pir.uid) != appId) {
5681                            // Different app id, skip it.
5682                            continue;
5683                        }
5684                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5685                            // Different user, skip it.
5686                            continue;
5687                        }
5688                        if (!pir.key.packageName.equals(name)) {
5689                            // Different package, skip it.
5690                            continue;
5691                        }
5692                    }
5693                    if (!doit) {
5694                        return true;
5695                    }
5696                    didSomething = true;
5697                    it.remove();
5698                    pir.canceled = true;
5699                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5700                        pir.key.activity.pendingResults.remove(pir.ref);
5701                    }
5702                }
5703            }
5704        }
5705
5706        if (doit) {
5707            if (purgeCache && name != null) {
5708                AttributeCache ac = AttributeCache.instance();
5709                if (ac != null) {
5710                    ac.removePackage(name);
5711                }
5712            }
5713            if (mBooted) {
5714                mStackSupervisor.resumeTopActivitiesLocked();
5715                mStackSupervisor.scheduleIdleLocked();
5716            }
5717        }
5718
5719        return didSomething;
5720    }
5721
5722    private final boolean removeProcessLocked(ProcessRecord app,
5723            boolean callerWillRestart, boolean allowRestart, String reason) {
5724        final String name = app.processName;
5725        final int uid = app.uid;
5726        if (DEBUG_PROCESSES) Slog.d(
5727            TAG, "Force removing proc " + app.toShortString() + " (" + name
5728            + "/" + uid + ")");
5729
5730        mProcessNames.remove(name, uid);
5731        mIsolatedProcesses.remove(app.uid);
5732        if (mHeavyWeightProcess == app) {
5733            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5734                    mHeavyWeightProcess.userId, 0));
5735            mHeavyWeightProcess = null;
5736        }
5737        boolean needRestart = false;
5738        if (app.pid > 0 && app.pid != MY_PID) {
5739            int pid = app.pid;
5740            synchronized (mPidsSelfLocked) {
5741                mPidsSelfLocked.remove(pid);
5742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5743            }
5744            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5745            if (app.isolated) {
5746                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5747            }
5748            app.kill(reason, true);
5749            handleAppDiedLocked(app, true, allowRestart);
5750            removeLruProcessLocked(app);
5751
5752            if (app.persistent && !app.isolated) {
5753                if (!callerWillRestart) {
5754                    addAppLocked(app.info, false, null /* ABI override */);
5755                } else {
5756                    needRestart = true;
5757                }
5758            }
5759        } else {
5760            mRemovedProcesses.add(app);
5761        }
5762
5763        return needRestart;
5764    }
5765
5766    private final void processStartTimedOutLocked(ProcessRecord app) {
5767        final int pid = app.pid;
5768        boolean gone = false;
5769        synchronized (mPidsSelfLocked) {
5770            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5771            if (knownApp != null && knownApp.thread == null) {
5772                mPidsSelfLocked.remove(pid);
5773                gone = true;
5774            }
5775        }
5776
5777        if (gone) {
5778            Slog.w(TAG, "Process " + app + " failed to attach");
5779            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5780                    pid, app.uid, app.processName);
5781            mProcessNames.remove(app.processName, app.uid);
5782            mIsolatedProcesses.remove(app.uid);
5783            if (mHeavyWeightProcess == app) {
5784                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5785                        mHeavyWeightProcess.userId, 0));
5786                mHeavyWeightProcess = null;
5787            }
5788            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5789            if (app.isolated) {
5790                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5791            }
5792            // Take care of any launching providers waiting for this process.
5793            checkAppInLaunchingProvidersLocked(app, true);
5794            // Take care of any services that are waiting for the process.
5795            mServices.processStartTimedOutLocked(app);
5796            app.kill("start timeout", true);
5797            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5798                Slog.w(TAG, "Unattached app died before backup, skipping");
5799                try {
5800                    IBackupManager bm = IBackupManager.Stub.asInterface(
5801                            ServiceManager.getService(Context.BACKUP_SERVICE));
5802                    bm.agentDisconnected(app.info.packageName);
5803                } catch (RemoteException e) {
5804                    // Can't happen; the backup manager is local
5805                }
5806            }
5807            if (isPendingBroadcastProcessLocked(pid)) {
5808                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5809                skipPendingBroadcastLocked(pid);
5810            }
5811        } else {
5812            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5813        }
5814    }
5815
5816    private final boolean attachApplicationLocked(IApplicationThread thread,
5817            int pid) {
5818
5819        // Find the application record that is being attached...  either via
5820        // the pid if we are running in multiple processes, or just pull the
5821        // next app record if we are emulating process with anonymous threads.
5822        ProcessRecord app;
5823        if (pid != MY_PID && pid >= 0) {
5824            synchronized (mPidsSelfLocked) {
5825                app = mPidsSelfLocked.get(pid);
5826            }
5827        } else {
5828            app = null;
5829        }
5830
5831        if (app == null) {
5832            Slog.w(TAG, "No pending application record for pid " + pid
5833                    + " (IApplicationThread " + thread + "); dropping process");
5834            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5835            if (pid > 0 && pid != MY_PID) {
5836                Process.killProcessQuiet(pid);
5837                //TODO: Process.killProcessGroup(app.info.uid, pid);
5838            } else {
5839                try {
5840                    thread.scheduleExit();
5841                } catch (Exception e) {
5842                    // Ignore exceptions.
5843                }
5844            }
5845            return false;
5846        }
5847
5848        // If this application record is still attached to a previous
5849        // process, clean it up now.
5850        if (app.thread != null) {
5851            handleAppDiedLocked(app, true, true);
5852        }
5853
5854        // Tell the process all about itself.
5855
5856        if (localLOGV) Slog.v(
5857                TAG, "Binding process pid " + pid + " to record " + app);
5858
5859        final String processName = app.processName;
5860        try {
5861            AppDeathRecipient adr = new AppDeathRecipient(
5862                    app, pid, thread);
5863            thread.asBinder().linkToDeath(adr, 0);
5864            app.deathRecipient = adr;
5865        } catch (RemoteException e) {
5866            app.resetPackageList(mProcessStats);
5867            startProcessLocked(app, "link fail", processName);
5868            return false;
5869        }
5870
5871        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5872
5873        app.makeActive(thread, mProcessStats);
5874        app.curAdj = app.setAdj = -100;
5875        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5876        app.forcingToForeground = null;
5877        updateProcessForegroundLocked(app, false, false);
5878        app.hasShownUi = false;
5879        app.debugging = false;
5880        app.cached = false;
5881
5882        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5883
5884        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5885        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5886
5887        if (!normalMode) {
5888            Slog.i(TAG, "Launching preboot mode app: " + app);
5889        }
5890
5891        if (localLOGV) Slog.v(
5892            TAG, "New app record " + app
5893            + " thread=" + thread.asBinder() + " pid=" + pid);
5894        try {
5895            int testMode = IApplicationThread.DEBUG_OFF;
5896            if (mDebugApp != null && mDebugApp.equals(processName)) {
5897                testMode = mWaitForDebugger
5898                    ? IApplicationThread.DEBUG_WAIT
5899                    : IApplicationThread.DEBUG_ON;
5900                app.debugging = true;
5901                if (mDebugTransient) {
5902                    mDebugApp = mOrigDebugApp;
5903                    mWaitForDebugger = mOrigWaitForDebugger;
5904                }
5905            }
5906            String profileFile = app.instrumentationProfileFile;
5907            ParcelFileDescriptor profileFd = null;
5908            int samplingInterval = 0;
5909            boolean profileAutoStop = false;
5910            if (mProfileApp != null && mProfileApp.equals(processName)) {
5911                mProfileProc = app;
5912                profileFile = mProfileFile;
5913                profileFd = mProfileFd;
5914                samplingInterval = mSamplingInterval;
5915                profileAutoStop = mAutoStopProfiler;
5916            }
5917            boolean enableOpenGlTrace = false;
5918            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5919                enableOpenGlTrace = true;
5920                mOpenGlTraceApp = null;
5921            }
5922
5923            // If the app is being launched for restore or full backup, set it up specially
5924            boolean isRestrictedBackupMode = false;
5925            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5926                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5927                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5928                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5929            }
5930
5931            ensurePackageDexOpt(app.instrumentationInfo != null
5932                    ? app.instrumentationInfo.packageName
5933                    : app.info.packageName);
5934            if (app.instrumentationClass != null) {
5935                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5936            }
5937            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5938                    + processName + " with config " + mConfiguration);
5939            ApplicationInfo appInfo = app.instrumentationInfo != null
5940                    ? app.instrumentationInfo : app.info;
5941            app.compat = compatibilityInfoForPackageLocked(appInfo);
5942            if (profileFd != null) {
5943                profileFd = profileFd.dup();
5944            }
5945            ProfilerInfo profilerInfo = profileFile == null ? null
5946                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5947            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5948                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5949                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5950                    isRestrictedBackupMode || !normalMode, app.persistent,
5951                    new Configuration(mConfiguration), app.compat,
5952                    getCommonServicesLocked(app.isolated),
5953                    mCoreSettingsObserver.getCoreSettingsLocked());
5954            updateLruProcessLocked(app, false, null);
5955            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5956        } catch (Exception e) {
5957            // todo: Yikes!  What should we do?  For now we will try to
5958            // start another process, but that could easily get us in
5959            // an infinite loop of restarting processes...
5960            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5961
5962            app.resetPackageList(mProcessStats);
5963            app.unlinkDeathRecipient();
5964            startProcessLocked(app, "bind fail", processName);
5965            return false;
5966        }
5967
5968        // Remove this record from the list of starting applications.
5969        mPersistentStartingProcesses.remove(app);
5970        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5971                "Attach application locked removing on hold: " + app);
5972        mProcessesOnHold.remove(app);
5973
5974        boolean badApp = false;
5975        boolean didSomething = false;
5976
5977        // See if the top visible activity is waiting to run in this process...
5978        if (normalMode) {
5979            try {
5980                if (mStackSupervisor.attachApplicationLocked(app)) {
5981                    didSomething = true;
5982                }
5983            } catch (Exception e) {
5984                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5985                badApp = true;
5986            }
5987        }
5988
5989        // Find any services that should be running in this process...
5990        if (!badApp) {
5991            try {
5992                didSomething |= mServices.attachApplicationLocked(app, processName);
5993            } catch (Exception e) {
5994                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5995                badApp = true;
5996            }
5997        }
5998
5999        // Check if a next-broadcast receiver is in this process...
6000        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6001            try {
6002                didSomething |= sendPendingBroadcastsLocked(app);
6003            } catch (Exception e) {
6004                // If the app died trying to launch the receiver we declare it 'bad'
6005                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6006                badApp = true;
6007            }
6008        }
6009
6010        // Check whether the next backup agent is in this process...
6011        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6012            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6013            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6014            try {
6015                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6016                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6017                        mBackupTarget.backupMode);
6018            } catch (Exception e) {
6019                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6020                badApp = true;
6021            }
6022        }
6023
6024        if (badApp) {
6025            app.kill("error during init", true);
6026            handleAppDiedLocked(app, false, true);
6027            return false;
6028        }
6029
6030        if (!didSomething) {
6031            updateOomAdjLocked();
6032        }
6033
6034        return true;
6035    }
6036
6037    @Override
6038    public final void attachApplication(IApplicationThread thread) {
6039        synchronized (this) {
6040            int callingPid = Binder.getCallingPid();
6041            final long origId = Binder.clearCallingIdentity();
6042            attachApplicationLocked(thread, callingPid);
6043            Binder.restoreCallingIdentity(origId);
6044        }
6045    }
6046
6047    @Override
6048    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6049        final long origId = Binder.clearCallingIdentity();
6050        synchronized (this) {
6051            ActivityStack stack = ActivityRecord.getStackLocked(token);
6052            if (stack != null) {
6053                ActivityRecord r =
6054                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6055                if (stopProfiling) {
6056                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6057                        try {
6058                            mProfileFd.close();
6059                        } catch (IOException e) {
6060                        }
6061                        clearProfilerLocked();
6062                    }
6063                }
6064            }
6065        }
6066        Binder.restoreCallingIdentity(origId);
6067    }
6068
6069    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6070        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6071                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6072    }
6073
6074    void enableScreenAfterBoot() {
6075        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6076                SystemClock.uptimeMillis());
6077        mWindowManager.enableScreenAfterBoot();
6078
6079        synchronized (this) {
6080            updateEventDispatchingLocked();
6081        }
6082    }
6083
6084    @Override
6085    public void showBootMessage(final CharSequence msg, final boolean always) {
6086        enforceNotIsolatedCaller("showBootMessage");
6087        mWindowManager.showBootMessage(msg, always);
6088    }
6089
6090    @Override
6091    public void keyguardWaitingForActivityDrawn() {
6092        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6093        final long token = Binder.clearCallingIdentity();
6094        try {
6095            synchronized (this) {
6096                if (DEBUG_LOCKSCREEN) logLockScreen("");
6097                mWindowManager.keyguardWaitingForActivityDrawn();
6098                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6099                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6100                    updateSleepIfNeededLocked();
6101                }
6102            }
6103        } finally {
6104            Binder.restoreCallingIdentity(token);
6105        }
6106    }
6107
6108    final void finishBooting() {
6109        synchronized (this) {
6110            if (!mBootAnimationComplete) {
6111                mCallFinishBooting = true;
6112                return;
6113            }
6114            mCallFinishBooting = false;
6115        }
6116
6117        ArraySet<String> completedIsas = new ArraySet<String>();
6118        for (String abi : Build.SUPPORTED_ABIS) {
6119            Process.establishZygoteConnectionForAbi(abi);
6120            final String instructionSet = VMRuntime.getInstructionSet(abi);
6121            if (!completedIsas.contains(instructionSet)) {
6122                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6123                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6124                }
6125                completedIsas.add(instructionSet);
6126            }
6127        }
6128
6129        IntentFilter pkgFilter = new IntentFilter();
6130        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6131        pkgFilter.addDataScheme("package");
6132        mContext.registerReceiver(new BroadcastReceiver() {
6133            @Override
6134            public void onReceive(Context context, Intent intent) {
6135                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6136                if (pkgs != null) {
6137                    for (String pkg : pkgs) {
6138                        synchronized (ActivityManagerService.this) {
6139                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6140                                    0, "finished booting")) {
6141                                setResultCode(Activity.RESULT_OK);
6142                                return;
6143                            }
6144                        }
6145                    }
6146                }
6147            }
6148        }, pkgFilter);
6149
6150        // Let system services know.
6151        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6152
6153        synchronized (this) {
6154            // Ensure that any processes we had put on hold are now started
6155            // up.
6156            final int NP = mProcessesOnHold.size();
6157            if (NP > 0) {
6158                ArrayList<ProcessRecord> procs =
6159                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6160                for (int ip=0; ip<NP; ip++) {
6161                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6162                            + procs.get(ip));
6163                    startProcessLocked(procs.get(ip), "on-hold", null);
6164                }
6165            }
6166
6167            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6168                // Start looking for apps that are abusing wake locks.
6169                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6170                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6171                // Tell anyone interested that we are done booting!
6172                SystemProperties.set("sys.boot_completed", "1");
6173
6174                // And trigger dev.bootcomplete if we are not showing encryption progress
6175                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6176                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6177                    SystemProperties.set("dev.bootcomplete", "1");
6178                }
6179                for (int i=0; i<mStartedUsers.size(); i++) {
6180                    UserStartedState uss = mStartedUsers.valueAt(i);
6181                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6182                        uss.mState = UserStartedState.STATE_RUNNING;
6183                        final int userId = mStartedUsers.keyAt(i);
6184                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6185                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6186                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6187                        broadcastIntentLocked(null, null, intent, null,
6188                                new IIntentReceiver.Stub() {
6189                                    @Override
6190                                    public void performReceive(Intent intent, int resultCode,
6191                                            String data, Bundle extras, boolean ordered,
6192                                            boolean sticky, int sendingUser) {
6193                                        synchronized (ActivityManagerService.this) {
6194                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6195                                                    true, false);
6196                                        }
6197                                    }
6198                                },
6199                                0, null, null,
6200                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6201                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6202                                userId);
6203                    }
6204                }
6205                scheduleStartProfilesLocked();
6206            }
6207        }
6208    }
6209
6210    @Override
6211    public void bootAnimationComplete() {
6212        final boolean callFinishBooting;
6213        synchronized (this) {
6214            callFinishBooting = mCallFinishBooting;
6215            mBootAnimationComplete = true;
6216        }
6217        if (callFinishBooting) {
6218            finishBooting();
6219        }
6220    }
6221
6222    final void ensureBootCompleted() {
6223        boolean booting;
6224        boolean enableScreen;
6225        synchronized (this) {
6226            booting = mBooting;
6227            mBooting = false;
6228            enableScreen = !mBooted;
6229            mBooted = true;
6230        }
6231
6232        if (booting) {
6233            finishBooting();
6234        }
6235
6236        if (enableScreen) {
6237            enableScreenAfterBoot();
6238        }
6239    }
6240
6241    @Override
6242    public final void activityResumed(IBinder token) {
6243        final long origId = Binder.clearCallingIdentity();
6244        synchronized(this) {
6245            ActivityStack stack = ActivityRecord.getStackLocked(token);
6246            if (stack != null) {
6247                ActivityRecord.activityResumedLocked(token);
6248            }
6249        }
6250        Binder.restoreCallingIdentity(origId);
6251    }
6252
6253    @Override
6254    public final void activityPaused(IBinder token) {
6255        final long origId = Binder.clearCallingIdentity();
6256        synchronized(this) {
6257            ActivityStack stack = ActivityRecord.getStackLocked(token);
6258            if (stack != null) {
6259                stack.activityPausedLocked(token, false);
6260            }
6261        }
6262        Binder.restoreCallingIdentity(origId);
6263    }
6264
6265    @Override
6266    public final void activityStopped(IBinder token, Bundle icicle,
6267            PersistableBundle persistentState, CharSequence description) {
6268        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6269
6270        // Refuse possible leaked file descriptors
6271        if (icicle != null && icicle.hasFileDescriptors()) {
6272            throw new IllegalArgumentException("File descriptors passed in Bundle");
6273        }
6274
6275        final long origId = Binder.clearCallingIdentity();
6276
6277        synchronized (this) {
6278            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6279            if (r != null) {
6280                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6281            }
6282        }
6283
6284        trimApplications();
6285
6286        Binder.restoreCallingIdentity(origId);
6287    }
6288
6289    @Override
6290    public final void activityDestroyed(IBinder token) {
6291        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6292        synchronized (this) {
6293            ActivityStack stack = ActivityRecord.getStackLocked(token);
6294            if (stack != null) {
6295                stack.activityDestroyedLocked(token);
6296            }
6297        }
6298    }
6299
6300    @Override
6301    public final void backgroundResourcesReleased(IBinder token) {
6302        final long origId = Binder.clearCallingIdentity();
6303        try {
6304            synchronized (this) {
6305                ActivityStack stack = ActivityRecord.getStackLocked(token);
6306                if (stack != null) {
6307                    stack.backgroundResourcesReleased();
6308                }
6309            }
6310        } finally {
6311            Binder.restoreCallingIdentity(origId);
6312        }
6313    }
6314
6315    @Override
6316    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6317        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6318    }
6319
6320    @Override
6321    public final void notifyEnterAnimationComplete(IBinder token) {
6322        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6323    }
6324
6325    @Override
6326    public String getCallingPackage(IBinder token) {
6327        synchronized (this) {
6328            ActivityRecord r = getCallingRecordLocked(token);
6329            return r != null ? r.info.packageName : null;
6330        }
6331    }
6332
6333    @Override
6334    public ComponentName getCallingActivity(IBinder token) {
6335        synchronized (this) {
6336            ActivityRecord r = getCallingRecordLocked(token);
6337            return r != null ? r.intent.getComponent() : null;
6338        }
6339    }
6340
6341    private ActivityRecord getCallingRecordLocked(IBinder token) {
6342        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6343        if (r == null) {
6344            return null;
6345        }
6346        return r.resultTo;
6347    }
6348
6349    @Override
6350    public ComponentName getActivityClassForToken(IBinder token) {
6351        synchronized(this) {
6352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6353            if (r == null) {
6354                return null;
6355            }
6356            return r.intent.getComponent();
6357        }
6358    }
6359
6360    @Override
6361    public String getPackageForToken(IBinder token) {
6362        synchronized(this) {
6363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6364            if (r == null) {
6365                return null;
6366            }
6367            return r.packageName;
6368        }
6369    }
6370
6371    @Override
6372    public IIntentSender getIntentSender(int type,
6373            String packageName, IBinder token, String resultWho,
6374            int requestCode, Intent[] intents, String[] resolvedTypes,
6375            int flags, Bundle options, int userId) {
6376        enforceNotIsolatedCaller("getIntentSender");
6377        // Refuse possible leaked file descriptors
6378        if (intents != null) {
6379            if (intents.length < 1) {
6380                throw new IllegalArgumentException("Intents array length must be >= 1");
6381            }
6382            for (int i=0; i<intents.length; i++) {
6383                Intent intent = intents[i];
6384                if (intent != null) {
6385                    if (intent.hasFileDescriptors()) {
6386                        throw new IllegalArgumentException("File descriptors passed in Intent");
6387                    }
6388                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6389                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6390                        throw new IllegalArgumentException(
6391                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6392                    }
6393                    intents[i] = new Intent(intent);
6394                }
6395            }
6396            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6397                throw new IllegalArgumentException(
6398                        "Intent array length does not match resolvedTypes length");
6399            }
6400        }
6401        if (options != null) {
6402            if (options.hasFileDescriptors()) {
6403                throw new IllegalArgumentException("File descriptors passed in options");
6404            }
6405        }
6406
6407        synchronized(this) {
6408            int callingUid = Binder.getCallingUid();
6409            int origUserId = userId;
6410            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6411                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6412                    ALLOW_NON_FULL, "getIntentSender", null);
6413            if (origUserId == UserHandle.USER_CURRENT) {
6414                // We don't want to evaluate this until the pending intent is
6415                // actually executed.  However, we do want to always do the
6416                // security checking for it above.
6417                userId = UserHandle.USER_CURRENT;
6418            }
6419            try {
6420                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6421                    int uid = AppGlobals.getPackageManager()
6422                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6423                    if (!UserHandle.isSameApp(callingUid, uid)) {
6424                        String msg = "Permission Denial: getIntentSender() from pid="
6425                            + Binder.getCallingPid()
6426                            + ", uid=" + Binder.getCallingUid()
6427                            + ", (need uid=" + uid + ")"
6428                            + " is not allowed to send as package " + packageName;
6429                        Slog.w(TAG, msg);
6430                        throw new SecurityException(msg);
6431                    }
6432                }
6433
6434                return getIntentSenderLocked(type, packageName, callingUid, userId,
6435                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6436
6437            } catch (RemoteException e) {
6438                throw new SecurityException(e);
6439            }
6440        }
6441    }
6442
6443    IIntentSender getIntentSenderLocked(int type, String packageName,
6444            int callingUid, int userId, IBinder token, String resultWho,
6445            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6446            Bundle options) {
6447        if (DEBUG_MU)
6448            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6449        ActivityRecord activity = null;
6450        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6451            activity = ActivityRecord.isInStackLocked(token);
6452            if (activity == null) {
6453                return null;
6454            }
6455            if (activity.finishing) {
6456                return null;
6457            }
6458        }
6459
6460        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6461        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6462        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6463        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6464                |PendingIntent.FLAG_UPDATE_CURRENT);
6465
6466        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6467                type, packageName, activity, resultWho,
6468                requestCode, intents, resolvedTypes, flags, options, userId);
6469        WeakReference<PendingIntentRecord> ref;
6470        ref = mIntentSenderRecords.get(key);
6471        PendingIntentRecord rec = ref != null ? ref.get() : null;
6472        if (rec != null) {
6473            if (!cancelCurrent) {
6474                if (updateCurrent) {
6475                    if (rec.key.requestIntent != null) {
6476                        rec.key.requestIntent.replaceExtras(intents != null ?
6477                                intents[intents.length - 1] : null);
6478                    }
6479                    if (intents != null) {
6480                        intents[intents.length-1] = rec.key.requestIntent;
6481                        rec.key.allIntents = intents;
6482                        rec.key.allResolvedTypes = resolvedTypes;
6483                    } else {
6484                        rec.key.allIntents = null;
6485                        rec.key.allResolvedTypes = null;
6486                    }
6487                }
6488                return rec;
6489            }
6490            rec.canceled = true;
6491            mIntentSenderRecords.remove(key);
6492        }
6493        if (noCreate) {
6494            return rec;
6495        }
6496        rec = new PendingIntentRecord(this, key, callingUid);
6497        mIntentSenderRecords.put(key, rec.ref);
6498        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6499            if (activity.pendingResults == null) {
6500                activity.pendingResults
6501                        = new HashSet<WeakReference<PendingIntentRecord>>();
6502            }
6503            activity.pendingResults.add(rec.ref);
6504        }
6505        return rec;
6506    }
6507
6508    @Override
6509    public void cancelIntentSender(IIntentSender sender) {
6510        if (!(sender instanceof PendingIntentRecord)) {
6511            return;
6512        }
6513        synchronized(this) {
6514            PendingIntentRecord rec = (PendingIntentRecord)sender;
6515            try {
6516                int uid = AppGlobals.getPackageManager()
6517                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6518                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6519                    String msg = "Permission Denial: cancelIntentSender() from pid="
6520                        + Binder.getCallingPid()
6521                        + ", uid=" + Binder.getCallingUid()
6522                        + " is not allowed to cancel packges "
6523                        + rec.key.packageName;
6524                    Slog.w(TAG, msg);
6525                    throw new SecurityException(msg);
6526                }
6527            } catch (RemoteException e) {
6528                throw new SecurityException(e);
6529            }
6530            cancelIntentSenderLocked(rec, true);
6531        }
6532    }
6533
6534    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6535        rec.canceled = true;
6536        mIntentSenderRecords.remove(rec.key);
6537        if (cleanActivity && rec.key.activity != null) {
6538            rec.key.activity.pendingResults.remove(rec.ref);
6539        }
6540    }
6541
6542    @Override
6543    public String getPackageForIntentSender(IIntentSender pendingResult) {
6544        if (!(pendingResult instanceof PendingIntentRecord)) {
6545            return null;
6546        }
6547        try {
6548            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6549            return res.key.packageName;
6550        } catch (ClassCastException e) {
6551        }
6552        return null;
6553    }
6554
6555    @Override
6556    public int getUidForIntentSender(IIntentSender sender) {
6557        if (sender instanceof PendingIntentRecord) {
6558            try {
6559                PendingIntentRecord res = (PendingIntentRecord)sender;
6560                return res.uid;
6561            } catch (ClassCastException e) {
6562            }
6563        }
6564        return -1;
6565    }
6566
6567    @Override
6568    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6569        if (!(pendingResult instanceof PendingIntentRecord)) {
6570            return false;
6571        }
6572        try {
6573            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6574            if (res.key.allIntents == null) {
6575                return false;
6576            }
6577            for (int i=0; i<res.key.allIntents.length; i++) {
6578                Intent intent = res.key.allIntents[i];
6579                if (intent.getPackage() != null && intent.getComponent() != null) {
6580                    return false;
6581                }
6582            }
6583            return true;
6584        } catch (ClassCastException e) {
6585        }
6586        return false;
6587    }
6588
6589    @Override
6590    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6591        if (!(pendingResult instanceof PendingIntentRecord)) {
6592            return false;
6593        }
6594        try {
6595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6596            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6597                return true;
6598            }
6599            return false;
6600        } catch (ClassCastException e) {
6601        }
6602        return false;
6603    }
6604
6605    @Override
6606    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6607        if (!(pendingResult instanceof PendingIntentRecord)) {
6608            return null;
6609        }
6610        try {
6611            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6612            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6613        } catch (ClassCastException e) {
6614        }
6615        return null;
6616    }
6617
6618    @Override
6619    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return null;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            Intent intent = res.key.requestIntent;
6626            if (intent != null) {
6627                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6628                        || res.lastTagPrefix.equals(prefix))) {
6629                    return res.lastTag;
6630                }
6631                res.lastTagPrefix = prefix;
6632                StringBuilder sb = new StringBuilder(128);
6633                if (prefix != null) {
6634                    sb.append(prefix);
6635                }
6636                if (intent.getAction() != null) {
6637                    sb.append(intent.getAction());
6638                } else if (intent.getComponent() != null) {
6639                    intent.getComponent().appendShortString(sb);
6640                } else {
6641                    sb.append("?");
6642                }
6643                return res.lastTag = sb.toString();
6644            }
6645        } catch (ClassCastException e) {
6646        }
6647        return null;
6648    }
6649
6650    @Override
6651    public void setProcessLimit(int max) {
6652        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6653                "setProcessLimit()");
6654        synchronized (this) {
6655            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6656            mProcessLimitOverride = max;
6657        }
6658        trimApplications();
6659    }
6660
6661    @Override
6662    public int getProcessLimit() {
6663        synchronized (this) {
6664            return mProcessLimitOverride;
6665        }
6666    }
6667
6668    void foregroundTokenDied(ForegroundToken token) {
6669        synchronized (ActivityManagerService.this) {
6670            synchronized (mPidsSelfLocked) {
6671                ForegroundToken cur
6672                    = mForegroundProcesses.get(token.pid);
6673                if (cur != token) {
6674                    return;
6675                }
6676                mForegroundProcesses.remove(token.pid);
6677                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6678                if (pr == null) {
6679                    return;
6680                }
6681                pr.forcingToForeground = null;
6682                updateProcessForegroundLocked(pr, false, false);
6683            }
6684            updateOomAdjLocked();
6685        }
6686    }
6687
6688    @Override
6689    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6690        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6691                "setProcessForeground()");
6692        synchronized(this) {
6693            boolean changed = false;
6694
6695            synchronized (mPidsSelfLocked) {
6696                ProcessRecord pr = mPidsSelfLocked.get(pid);
6697                if (pr == null && isForeground) {
6698                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6699                    return;
6700                }
6701                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6702                if (oldToken != null) {
6703                    oldToken.token.unlinkToDeath(oldToken, 0);
6704                    mForegroundProcesses.remove(pid);
6705                    if (pr != null) {
6706                        pr.forcingToForeground = null;
6707                    }
6708                    changed = true;
6709                }
6710                if (isForeground && token != null) {
6711                    ForegroundToken newToken = new ForegroundToken() {
6712                        @Override
6713                        public void binderDied() {
6714                            foregroundTokenDied(this);
6715                        }
6716                    };
6717                    newToken.pid = pid;
6718                    newToken.token = token;
6719                    try {
6720                        token.linkToDeath(newToken, 0);
6721                        mForegroundProcesses.put(pid, newToken);
6722                        pr.forcingToForeground = token;
6723                        changed = true;
6724                    } catch (RemoteException e) {
6725                        // If the process died while doing this, we will later
6726                        // do the cleanup with the process death link.
6727                    }
6728                }
6729            }
6730
6731            if (changed) {
6732                updateOomAdjLocked();
6733            }
6734        }
6735    }
6736
6737    // =========================================================
6738    // PERMISSIONS
6739    // =========================================================
6740
6741    static class PermissionController extends IPermissionController.Stub {
6742        ActivityManagerService mActivityManagerService;
6743        PermissionController(ActivityManagerService activityManagerService) {
6744            mActivityManagerService = activityManagerService;
6745        }
6746
6747        @Override
6748        public boolean checkPermission(String permission, int pid, int uid) {
6749            return mActivityManagerService.checkPermission(permission, pid,
6750                    uid) == PackageManager.PERMISSION_GRANTED;
6751        }
6752    }
6753
6754    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6755        @Override
6756        public int checkComponentPermission(String permission, int pid, int uid,
6757                int owningUid, boolean exported) {
6758            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6759                    owningUid, exported);
6760        }
6761
6762        @Override
6763        public Object getAMSLock() {
6764            return ActivityManagerService.this;
6765        }
6766    }
6767
6768    /**
6769     * This can be called with or without the global lock held.
6770     */
6771    int checkComponentPermission(String permission, int pid, int uid,
6772            int owningUid, boolean exported) {
6773        if (pid == MY_PID) {
6774            return PackageManager.PERMISSION_GRANTED;
6775        }
6776        return ActivityManager.checkComponentPermission(permission, uid,
6777                owningUid, exported);
6778    }
6779
6780    /**
6781     * As the only public entry point for permissions checking, this method
6782     * can enforce the semantic that requesting a check on a null global
6783     * permission is automatically denied.  (Internally a null permission
6784     * string is used when calling {@link #checkComponentPermission} in cases
6785     * when only uid-based security is needed.)
6786     *
6787     * This can be called with or without the global lock held.
6788     */
6789    @Override
6790    public int checkPermission(String permission, int pid, int uid) {
6791        if (permission == null) {
6792            return PackageManager.PERMISSION_DENIED;
6793        }
6794        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6795    }
6796
6797    @Override
6798    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6799        if (permission == null) {
6800            return PackageManager.PERMISSION_DENIED;
6801        }
6802
6803        // We might be performing an operation on behalf of an indirect binder
6804        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6805        // client identity accordingly before proceeding.
6806        Identity tlsIdentity = sCallerIdentity.get();
6807        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6808            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6809                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6810            uid = tlsIdentity.uid;
6811            pid = tlsIdentity.pid;
6812        }
6813
6814        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6815    }
6816
6817    /**
6818     * Binder IPC calls go through the public entry point.
6819     * This can be called with or without the global lock held.
6820     */
6821    int checkCallingPermission(String permission) {
6822        return checkPermission(permission,
6823                Binder.getCallingPid(),
6824                UserHandle.getAppId(Binder.getCallingUid()));
6825    }
6826
6827    /**
6828     * This can be called with or without the global lock held.
6829     */
6830    void enforceCallingPermission(String permission, String func) {
6831        if (checkCallingPermission(permission)
6832                == PackageManager.PERMISSION_GRANTED) {
6833            return;
6834        }
6835
6836        String msg = "Permission Denial: " + func + " from pid="
6837                + Binder.getCallingPid()
6838                + ", uid=" + Binder.getCallingUid()
6839                + " requires " + permission;
6840        Slog.w(TAG, msg);
6841        throw new SecurityException(msg);
6842    }
6843
6844    /**
6845     * Determine if UID is holding permissions required to access {@link Uri} in
6846     * the given {@link ProviderInfo}. Final permission checking is always done
6847     * in {@link ContentProvider}.
6848     */
6849    private final boolean checkHoldingPermissionsLocked(
6850            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6851        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6852                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6853        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6854            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6855                    != PERMISSION_GRANTED) {
6856                return false;
6857            }
6858        }
6859        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6860    }
6861
6862    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6863            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6864        if (pi.applicationInfo.uid == uid) {
6865            return true;
6866        } else if (!pi.exported) {
6867            return false;
6868        }
6869
6870        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6871        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6872        try {
6873            // check if target holds top-level <provider> permissions
6874            if (!readMet && pi.readPermission != null && considerUidPermissions
6875                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6876                readMet = true;
6877            }
6878            if (!writeMet && pi.writePermission != null && considerUidPermissions
6879                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6880                writeMet = true;
6881            }
6882
6883            // track if unprotected read/write is allowed; any denied
6884            // <path-permission> below removes this ability
6885            boolean allowDefaultRead = pi.readPermission == null;
6886            boolean allowDefaultWrite = pi.writePermission == null;
6887
6888            // check if target holds any <path-permission> that match uri
6889            final PathPermission[] pps = pi.pathPermissions;
6890            if (pps != null) {
6891                final String path = grantUri.uri.getPath();
6892                int i = pps.length;
6893                while (i > 0 && (!readMet || !writeMet)) {
6894                    i--;
6895                    PathPermission pp = pps[i];
6896                    if (pp.match(path)) {
6897                        if (!readMet) {
6898                            final String pprperm = pp.getReadPermission();
6899                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6900                                    + pprperm + " for " + pp.getPath()
6901                                    + ": match=" + pp.match(path)
6902                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6903                            if (pprperm != null) {
6904                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6905                                        == PERMISSION_GRANTED) {
6906                                    readMet = true;
6907                                } else {
6908                                    allowDefaultRead = false;
6909                                }
6910                            }
6911                        }
6912                        if (!writeMet) {
6913                            final String ppwperm = pp.getWritePermission();
6914                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6915                                    + ppwperm + " for " + pp.getPath()
6916                                    + ": match=" + pp.match(path)
6917                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6918                            if (ppwperm != null) {
6919                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6920                                        == PERMISSION_GRANTED) {
6921                                    writeMet = true;
6922                                } else {
6923                                    allowDefaultWrite = false;
6924                                }
6925                            }
6926                        }
6927                    }
6928                }
6929            }
6930
6931            // grant unprotected <provider> read/write, if not blocked by
6932            // <path-permission> above
6933            if (allowDefaultRead) readMet = true;
6934            if (allowDefaultWrite) writeMet = true;
6935
6936        } catch (RemoteException e) {
6937            return false;
6938        }
6939
6940        return readMet && writeMet;
6941    }
6942
6943    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6944        ProviderInfo pi = null;
6945        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6946        if (cpr != null) {
6947            pi = cpr.info;
6948        } else {
6949            try {
6950                pi = AppGlobals.getPackageManager().resolveContentProvider(
6951                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6952            } catch (RemoteException ex) {
6953            }
6954        }
6955        return pi;
6956    }
6957
6958    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6959        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6960        if (targetUris != null) {
6961            return targetUris.get(grantUri);
6962        }
6963        return null;
6964    }
6965
6966    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6967            String targetPkg, int targetUid, GrantUri grantUri) {
6968        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6969        if (targetUris == null) {
6970            targetUris = Maps.newArrayMap();
6971            mGrantedUriPermissions.put(targetUid, targetUris);
6972        }
6973
6974        UriPermission perm = targetUris.get(grantUri);
6975        if (perm == null) {
6976            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6977            targetUris.put(grantUri, perm);
6978        }
6979
6980        return perm;
6981    }
6982
6983    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6984            final int modeFlags) {
6985        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6986        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6987                : UriPermission.STRENGTH_OWNED;
6988
6989        // Root gets to do everything.
6990        if (uid == 0) {
6991            return true;
6992        }
6993
6994        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6995        if (perms == null) return false;
6996
6997        // First look for exact match
6998        final UriPermission exactPerm = perms.get(grantUri);
6999        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7000            return true;
7001        }
7002
7003        // No exact match, look for prefixes
7004        final int N = perms.size();
7005        for (int i = 0; i < N; i++) {
7006            final UriPermission perm = perms.valueAt(i);
7007            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7008                    && perm.getStrength(modeFlags) >= minStrength) {
7009                return true;
7010            }
7011        }
7012
7013        return false;
7014    }
7015
7016    /**
7017     * @param uri This uri must NOT contain an embedded userId.
7018     * @param userId The userId in which the uri is to be resolved.
7019     */
7020    @Override
7021    public int checkUriPermission(Uri uri, int pid, int uid,
7022            final int modeFlags, int userId, IBinder callerToken) {
7023        enforceNotIsolatedCaller("checkUriPermission");
7024
7025        // Another redirected-binder-call permissions check as in
7026        // {@link checkPermissionWithToken}.
7027        Identity tlsIdentity = sCallerIdentity.get();
7028        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7029            uid = tlsIdentity.uid;
7030            pid = tlsIdentity.pid;
7031        }
7032
7033        // Our own process gets to do everything.
7034        if (pid == MY_PID) {
7035            return PackageManager.PERMISSION_GRANTED;
7036        }
7037        synchronized (this) {
7038            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7039                    ? PackageManager.PERMISSION_GRANTED
7040                    : PackageManager.PERMISSION_DENIED;
7041        }
7042    }
7043
7044    /**
7045     * Check if the targetPkg can be granted permission to access uri by
7046     * the callingUid using the given modeFlags.  Throws a security exception
7047     * if callingUid is not allowed to do this.  Returns the uid of the target
7048     * if the URI permission grant should be performed; returns -1 if it is not
7049     * needed (for example targetPkg already has permission to access the URI).
7050     * If you already know the uid of the target, you can supply it in
7051     * lastTargetUid else set that to -1.
7052     */
7053    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7054            final int modeFlags, int lastTargetUid) {
7055        if (!Intent.isAccessUriMode(modeFlags)) {
7056            return -1;
7057        }
7058
7059        if (targetPkg != null) {
7060            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7061                    "Checking grant " + targetPkg + " permission to " + grantUri);
7062        }
7063
7064        final IPackageManager pm = AppGlobals.getPackageManager();
7065
7066        // If this is not a content: uri, we can't do anything with it.
7067        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7068            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7069                    "Can't grant URI permission for non-content URI: " + grantUri);
7070            return -1;
7071        }
7072
7073        final String authority = grantUri.uri.getAuthority();
7074        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7075        if (pi == null) {
7076            Slog.w(TAG, "No content provider found for permission check: " +
7077                    grantUri.uri.toSafeString());
7078            return -1;
7079        }
7080
7081        int targetUid = lastTargetUid;
7082        if (targetUid < 0 && targetPkg != null) {
7083            try {
7084                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7085                if (targetUid < 0) {
7086                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7087                            "Can't grant URI permission no uid for: " + targetPkg);
7088                    return -1;
7089                }
7090            } catch (RemoteException ex) {
7091                return -1;
7092            }
7093        }
7094
7095        if (targetUid >= 0) {
7096            // First...  does the target actually need this permission?
7097            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7098                // No need to grant the target this permission.
7099                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7100                        "Target " + targetPkg + " already has full permission to " + grantUri);
7101                return -1;
7102            }
7103        } else {
7104            // First...  there is no target package, so can anyone access it?
7105            boolean allowed = pi.exported;
7106            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7107                if (pi.readPermission != null) {
7108                    allowed = false;
7109                }
7110            }
7111            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7112                if (pi.writePermission != null) {
7113                    allowed = false;
7114                }
7115            }
7116            if (allowed) {
7117                return -1;
7118            }
7119        }
7120
7121        /* There is a special cross user grant if:
7122         * - The target is on another user.
7123         * - Apps on the current user can access the uri without any uid permissions.
7124         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7125         * grant uri permissions.
7126         */
7127        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7128                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7129                modeFlags, false /*without considering the uid permissions*/);
7130
7131        // Second...  is the provider allowing granting of URI permissions?
7132        if (!specialCrossUserGrant) {
7133            if (!pi.grantUriPermissions) {
7134                throw new SecurityException("Provider " + pi.packageName
7135                        + "/" + pi.name
7136                        + " does not allow granting of Uri permissions (uri "
7137                        + grantUri + ")");
7138            }
7139            if (pi.uriPermissionPatterns != null) {
7140                final int N = pi.uriPermissionPatterns.length;
7141                boolean allowed = false;
7142                for (int i=0; i<N; i++) {
7143                    if (pi.uriPermissionPatterns[i] != null
7144                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7145                        allowed = true;
7146                        break;
7147                    }
7148                }
7149                if (!allowed) {
7150                    throw new SecurityException("Provider " + pi.packageName
7151                            + "/" + pi.name
7152                            + " does not allow granting of permission to path of Uri "
7153                            + grantUri);
7154                }
7155            }
7156        }
7157
7158        // Third...  does the caller itself have permission to access
7159        // this uri?
7160        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7161            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7162                // Require they hold a strong enough Uri permission
7163                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7164                    throw new SecurityException("Uid " + callingUid
7165                            + " does not have permission to uri " + grantUri);
7166                }
7167            }
7168        }
7169        return targetUid;
7170    }
7171
7172    /**
7173     * @param uri This uri must NOT contain an embedded userId.
7174     * @param userId The userId in which the uri is to be resolved.
7175     */
7176    @Override
7177    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7178            final int modeFlags, int userId) {
7179        enforceNotIsolatedCaller("checkGrantUriPermission");
7180        synchronized(this) {
7181            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7182                    new GrantUri(userId, uri, false), modeFlags, -1);
7183        }
7184    }
7185
7186    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7187            final int modeFlags, UriPermissionOwner owner) {
7188        if (!Intent.isAccessUriMode(modeFlags)) {
7189            return;
7190        }
7191
7192        // So here we are: the caller has the assumed permission
7193        // to the uri, and the target doesn't.  Let's now give this to
7194        // the target.
7195
7196        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7197                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7198
7199        final String authority = grantUri.uri.getAuthority();
7200        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7201        if (pi == null) {
7202            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7203            return;
7204        }
7205
7206        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7207            grantUri.prefix = true;
7208        }
7209        final UriPermission perm = findOrCreateUriPermissionLocked(
7210                pi.packageName, targetPkg, targetUid, grantUri);
7211        perm.grantModes(modeFlags, owner);
7212    }
7213
7214    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7215            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7216        if (targetPkg == null) {
7217            throw new NullPointerException("targetPkg");
7218        }
7219        int targetUid;
7220        final IPackageManager pm = AppGlobals.getPackageManager();
7221        try {
7222            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7223        } catch (RemoteException ex) {
7224            return;
7225        }
7226
7227        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7228                targetUid);
7229        if (targetUid < 0) {
7230            return;
7231        }
7232
7233        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7234                owner);
7235    }
7236
7237    static class NeededUriGrants extends ArrayList<GrantUri> {
7238        final String targetPkg;
7239        final int targetUid;
7240        final int flags;
7241
7242        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7243            this.targetPkg = targetPkg;
7244            this.targetUid = targetUid;
7245            this.flags = flags;
7246        }
7247    }
7248
7249    /**
7250     * Like checkGrantUriPermissionLocked, but takes an Intent.
7251     */
7252    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7253            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7254        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7255                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7256                + " clip=" + (intent != null ? intent.getClipData() : null)
7257                + " from " + intent + "; flags=0x"
7258                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7259
7260        if (targetPkg == null) {
7261            throw new NullPointerException("targetPkg");
7262        }
7263
7264        if (intent == null) {
7265            return null;
7266        }
7267        Uri data = intent.getData();
7268        ClipData clip = intent.getClipData();
7269        if (data == null && clip == null) {
7270            return null;
7271        }
7272        // Default userId for uris in the intent (if they don't specify it themselves)
7273        int contentUserHint = intent.getContentUserHint();
7274        if (contentUserHint == UserHandle.USER_CURRENT) {
7275            contentUserHint = UserHandle.getUserId(callingUid);
7276        }
7277        final IPackageManager pm = AppGlobals.getPackageManager();
7278        int targetUid;
7279        if (needed != null) {
7280            targetUid = needed.targetUid;
7281        } else {
7282            try {
7283                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7284            } catch (RemoteException ex) {
7285                return null;
7286            }
7287            if (targetUid < 0) {
7288                if (DEBUG_URI_PERMISSION) {
7289                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7290                            + " on user " + targetUserId);
7291                }
7292                return null;
7293            }
7294        }
7295        if (data != null) {
7296            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7297            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7298                    targetUid);
7299            if (targetUid > 0) {
7300                if (needed == null) {
7301                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7302                }
7303                needed.add(grantUri);
7304            }
7305        }
7306        if (clip != null) {
7307            for (int i=0; i<clip.getItemCount(); i++) {
7308                Uri uri = clip.getItemAt(i).getUri();
7309                if (uri != null) {
7310                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7311                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7312                            targetUid);
7313                    if (targetUid > 0) {
7314                        if (needed == null) {
7315                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7316                        }
7317                        needed.add(grantUri);
7318                    }
7319                } else {
7320                    Intent clipIntent = clip.getItemAt(i).getIntent();
7321                    if (clipIntent != null) {
7322                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7323                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7324                        if (newNeeded != null) {
7325                            needed = newNeeded;
7326                        }
7327                    }
7328                }
7329            }
7330        }
7331
7332        return needed;
7333    }
7334
7335    /**
7336     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7337     */
7338    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7339            UriPermissionOwner owner) {
7340        if (needed != null) {
7341            for (int i=0; i<needed.size(); i++) {
7342                GrantUri grantUri = needed.get(i);
7343                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7344                        grantUri, needed.flags, owner);
7345            }
7346        }
7347    }
7348
7349    void grantUriPermissionFromIntentLocked(int callingUid,
7350            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7351        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7352                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7353        if (needed == null) {
7354            return;
7355        }
7356
7357        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7358    }
7359
7360    /**
7361     * @param uri This uri must NOT contain an embedded userId.
7362     * @param userId The userId in which the uri is to be resolved.
7363     */
7364    @Override
7365    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7366            final int modeFlags, int userId) {
7367        enforceNotIsolatedCaller("grantUriPermission");
7368        GrantUri grantUri = new GrantUri(userId, uri, false);
7369        synchronized(this) {
7370            final ProcessRecord r = getRecordForAppLocked(caller);
7371            if (r == null) {
7372                throw new SecurityException("Unable to find app for caller "
7373                        + caller
7374                        + " when granting permission to uri " + grantUri);
7375            }
7376            if (targetPkg == null) {
7377                throw new IllegalArgumentException("null target");
7378            }
7379            if (grantUri == null) {
7380                throw new IllegalArgumentException("null uri");
7381            }
7382
7383            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7384                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7385                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7386                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7387
7388            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7389                    UserHandle.getUserId(r.uid));
7390        }
7391    }
7392
7393    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7394        if (perm.modeFlags == 0) {
7395            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7396                    perm.targetUid);
7397            if (perms != null) {
7398                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7399                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7400
7401                perms.remove(perm.uri);
7402                if (perms.isEmpty()) {
7403                    mGrantedUriPermissions.remove(perm.targetUid);
7404                }
7405            }
7406        }
7407    }
7408
7409    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7410        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7411
7412        final IPackageManager pm = AppGlobals.getPackageManager();
7413        final String authority = grantUri.uri.getAuthority();
7414        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7415        if (pi == null) {
7416            Slog.w(TAG, "No content provider found for permission revoke: "
7417                    + grantUri.toSafeString());
7418            return;
7419        }
7420
7421        // Does the caller have this permission on the URI?
7422        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7423            // If they don't have direct access to the URI, then revoke any
7424            // ownerless URI permissions that have been granted to them.
7425            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7426            if (perms != null) {
7427                boolean persistChanged = false;
7428                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7429                    final UriPermission perm = it.next();
7430                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7431                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7432                        if (DEBUG_URI_PERMISSION)
7433                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7434                                    " permission to " + perm.uri);
7435                        persistChanged |= perm.revokeModes(
7436                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7437                        if (perm.modeFlags == 0) {
7438                            it.remove();
7439                        }
7440                    }
7441                }
7442                if (perms.isEmpty()) {
7443                    mGrantedUriPermissions.remove(callingUid);
7444                }
7445                if (persistChanged) {
7446                    schedulePersistUriGrants();
7447                }
7448            }
7449            return;
7450        }
7451
7452        boolean persistChanged = false;
7453
7454        // Go through all of the permissions and remove any that match.
7455        int N = mGrantedUriPermissions.size();
7456        for (int i = 0; i < N; i++) {
7457            final int targetUid = mGrantedUriPermissions.keyAt(i);
7458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7459
7460            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7461                final UriPermission perm = it.next();
7462                if (perm.uri.sourceUserId == grantUri.sourceUserId
7463                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7464                    if (DEBUG_URI_PERMISSION)
7465                        Slog.v(TAG,
7466                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7467                    persistChanged |= perm.revokeModes(
7468                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7469                    if (perm.modeFlags == 0) {
7470                        it.remove();
7471                    }
7472                }
7473            }
7474
7475            if (perms.isEmpty()) {
7476                mGrantedUriPermissions.remove(targetUid);
7477                N--;
7478                i--;
7479            }
7480        }
7481
7482        if (persistChanged) {
7483            schedulePersistUriGrants();
7484        }
7485    }
7486
7487    /**
7488     * @param uri This uri must NOT contain an embedded userId.
7489     * @param userId The userId in which the uri is to be resolved.
7490     */
7491    @Override
7492    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7493            int userId) {
7494        enforceNotIsolatedCaller("revokeUriPermission");
7495        synchronized(this) {
7496            final ProcessRecord r = getRecordForAppLocked(caller);
7497            if (r == null) {
7498                throw new SecurityException("Unable to find app for caller "
7499                        + caller
7500                        + " when revoking permission to uri " + uri);
7501            }
7502            if (uri == null) {
7503                Slog.w(TAG, "revokeUriPermission: null uri");
7504                return;
7505            }
7506
7507            if (!Intent.isAccessUriMode(modeFlags)) {
7508                return;
7509            }
7510
7511            final IPackageManager pm = AppGlobals.getPackageManager();
7512            final String authority = uri.getAuthority();
7513            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7514            if (pi == null) {
7515                Slog.w(TAG, "No content provider found for permission revoke: "
7516                        + uri.toSafeString());
7517                return;
7518            }
7519
7520            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7521        }
7522    }
7523
7524    /**
7525     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7526     * given package.
7527     *
7528     * @param packageName Package name to match, or {@code null} to apply to all
7529     *            packages.
7530     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7531     *            to all users.
7532     * @param persistable If persistable grants should be removed.
7533     */
7534    private void removeUriPermissionsForPackageLocked(
7535            String packageName, int userHandle, boolean persistable) {
7536        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7537            throw new IllegalArgumentException("Must narrow by either package or user");
7538        }
7539
7540        boolean persistChanged = false;
7541
7542        int N = mGrantedUriPermissions.size();
7543        for (int i = 0; i < N; i++) {
7544            final int targetUid = mGrantedUriPermissions.keyAt(i);
7545            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7546
7547            // Only inspect grants matching user
7548            if (userHandle == UserHandle.USER_ALL
7549                    || userHandle == UserHandle.getUserId(targetUid)) {
7550                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7551                    final UriPermission perm = it.next();
7552
7553                    // Only inspect grants matching package
7554                    if (packageName == null || perm.sourcePkg.equals(packageName)
7555                            || perm.targetPkg.equals(packageName)) {
7556                        persistChanged |= perm.revokeModes(persistable
7557                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7558
7559                        // Only remove when no modes remain; any persisted grants
7560                        // will keep this alive.
7561                        if (perm.modeFlags == 0) {
7562                            it.remove();
7563                        }
7564                    }
7565                }
7566
7567                if (perms.isEmpty()) {
7568                    mGrantedUriPermissions.remove(targetUid);
7569                    N--;
7570                    i--;
7571                }
7572            }
7573        }
7574
7575        if (persistChanged) {
7576            schedulePersistUriGrants();
7577        }
7578    }
7579
7580    @Override
7581    public IBinder newUriPermissionOwner(String name) {
7582        enforceNotIsolatedCaller("newUriPermissionOwner");
7583        synchronized(this) {
7584            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7585            return owner.getExternalTokenLocked();
7586        }
7587    }
7588
7589    /**
7590     * @param uri This uri must NOT contain an embedded userId.
7591     * @param sourceUserId The userId in which the uri is to be resolved.
7592     * @param targetUserId The userId of the app that receives the grant.
7593     */
7594    @Override
7595    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7596            final int modeFlags, int sourceUserId, int targetUserId) {
7597        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7598                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7599        synchronized(this) {
7600            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7601            if (owner == null) {
7602                throw new IllegalArgumentException("Unknown owner: " + token);
7603            }
7604            if (fromUid != Binder.getCallingUid()) {
7605                if (Binder.getCallingUid() != Process.myUid()) {
7606                    // Only system code can grant URI permissions on behalf
7607                    // of other users.
7608                    throw new SecurityException("nice try");
7609                }
7610            }
7611            if (targetPkg == null) {
7612                throw new IllegalArgumentException("null target");
7613            }
7614            if (uri == null) {
7615                throw new IllegalArgumentException("null uri");
7616            }
7617
7618            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7619                    modeFlags, owner, targetUserId);
7620        }
7621    }
7622
7623    /**
7624     * @param uri This uri must NOT contain an embedded userId.
7625     * @param userId The userId in which the uri is to be resolved.
7626     */
7627    @Override
7628    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7629        synchronized(this) {
7630            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7631            if (owner == null) {
7632                throw new IllegalArgumentException("Unknown owner: " + token);
7633            }
7634
7635            if (uri == null) {
7636                owner.removeUriPermissionsLocked(mode);
7637            } else {
7638                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7639            }
7640        }
7641    }
7642
7643    private void schedulePersistUriGrants() {
7644        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7645            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7646                    10 * DateUtils.SECOND_IN_MILLIS);
7647        }
7648    }
7649
7650    private void writeGrantedUriPermissions() {
7651        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7652
7653        // Snapshot permissions so we can persist without lock
7654        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7655        synchronized (this) {
7656            final int size = mGrantedUriPermissions.size();
7657            for (int i = 0; i < size; i++) {
7658                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7659                for (UriPermission perm : perms.values()) {
7660                    if (perm.persistedModeFlags != 0) {
7661                        persist.add(perm.snapshot());
7662                    }
7663                }
7664            }
7665        }
7666
7667        FileOutputStream fos = null;
7668        try {
7669            fos = mGrantFile.startWrite();
7670
7671            XmlSerializer out = new FastXmlSerializer();
7672            out.setOutput(fos, "utf-8");
7673            out.startDocument(null, true);
7674            out.startTag(null, TAG_URI_GRANTS);
7675            for (UriPermission.Snapshot perm : persist) {
7676                out.startTag(null, TAG_URI_GRANT);
7677                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7678                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7679                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7680                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7681                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7682                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7683                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7684                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7685                out.endTag(null, TAG_URI_GRANT);
7686            }
7687            out.endTag(null, TAG_URI_GRANTS);
7688            out.endDocument();
7689
7690            mGrantFile.finishWrite(fos);
7691        } catch (IOException e) {
7692            if (fos != null) {
7693                mGrantFile.failWrite(fos);
7694            }
7695        }
7696    }
7697
7698    private void readGrantedUriPermissionsLocked() {
7699        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7700
7701        final long now = System.currentTimeMillis();
7702
7703        FileInputStream fis = null;
7704        try {
7705            fis = mGrantFile.openRead();
7706            final XmlPullParser in = Xml.newPullParser();
7707            in.setInput(fis, null);
7708
7709            int type;
7710            while ((type = in.next()) != END_DOCUMENT) {
7711                final String tag = in.getName();
7712                if (type == START_TAG) {
7713                    if (TAG_URI_GRANT.equals(tag)) {
7714                        final int sourceUserId;
7715                        final int targetUserId;
7716                        final int userHandle = readIntAttribute(in,
7717                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7718                        if (userHandle != UserHandle.USER_NULL) {
7719                            // For backwards compatibility.
7720                            sourceUserId = userHandle;
7721                            targetUserId = userHandle;
7722                        } else {
7723                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7724                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7725                        }
7726                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7727                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7728                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7729                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7730                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7731                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7732
7733                        // Sanity check that provider still belongs to source package
7734                        final ProviderInfo pi = getProviderInfoLocked(
7735                                uri.getAuthority(), sourceUserId);
7736                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7737                            int targetUid = -1;
7738                            try {
7739                                targetUid = AppGlobals.getPackageManager()
7740                                        .getPackageUid(targetPkg, targetUserId);
7741                            } catch (RemoteException e) {
7742                            }
7743                            if (targetUid != -1) {
7744                                final UriPermission perm = findOrCreateUriPermissionLocked(
7745                                        sourcePkg, targetPkg, targetUid,
7746                                        new GrantUri(sourceUserId, uri, prefix));
7747                                perm.initPersistedModes(modeFlags, createdTime);
7748                            }
7749                        } else {
7750                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7751                                    + " but instead found " + pi);
7752                        }
7753                    }
7754                }
7755            }
7756        } catch (FileNotFoundException e) {
7757            // Missing grants is okay
7758        } catch (IOException e) {
7759            Slog.wtf(TAG, "Failed reading Uri grants", e);
7760        } catch (XmlPullParserException e) {
7761            Slog.wtf(TAG, "Failed reading Uri grants", e);
7762        } finally {
7763            IoUtils.closeQuietly(fis);
7764        }
7765    }
7766
7767    /**
7768     * @param uri This uri must NOT contain an embedded userId.
7769     * @param userId The userId in which the uri is to be resolved.
7770     */
7771    @Override
7772    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7773        enforceNotIsolatedCaller("takePersistableUriPermission");
7774
7775        Preconditions.checkFlagsArgument(modeFlags,
7776                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7777
7778        synchronized (this) {
7779            final int callingUid = Binder.getCallingUid();
7780            boolean persistChanged = false;
7781            GrantUri grantUri = new GrantUri(userId, uri, false);
7782
7783            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, false));
7785            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7786                    new GrantUri(userId, uri, true));
7787
7788            final boolean exactValid = (exactPerm != null)
7789                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7790            final boolean prefixValid = (prefixPerm != null)
7791                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7792
7793            if (!(exactValid || prefixValid)) {
7794                throw new SecurityException("No persistable permission grants found for UID "
7795                        + callingUid + " and Uri " + grantUri.toSafeString());
7796            }
7797
7798            if (exactValid) {
7799                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7800            }
7801            if (prefixValid) {
7802                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7803            }
7804
7805            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7806
7807            if (persistChanged) {
7808                schedulePersistUriGrants();
7809            }
7810        }
7811    }
7812
7813    /**
7814     * @param uri This uri must NOT contain an embedded userId.
7815     * @param userId The userId in which the uri is to be resolved.
7816     */
7817    @Override
7818    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7819        enforceNotIsolatedCaller("releasePersistableUriPermission");
7820
7821        Preconditions.checkFlagsArgument(modeFlags,
7822                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7823
7824        synchronized (this) {
7825            final int callingUid = Binder.getCallingUid();
7826            boolean persistChanged = false;
7827
7828            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, false));
7830            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7831                    new GrantUri(userId, uri, true));
7832            if (exactPerm == null && prefixPerm == null) {
7833                throw new SecurityException("No permission grants found for UID " + callingUid
7834                        + " and Uri " + uri.toSafeString());
7835            }
7836
7837            if (exactPerm != null) {
7838                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7839                removeUriPermissionIfNeededLocked(exactPerm);
7840            }
7841            if (prefixPerm != null) {
7842                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7843                removeUriPermissionIfNeededLocked(prefixPerm);
7844            }
7845
7846            if (persistChanged) {
7847                schedulePersistUriGrants();
7848            }
7849        }
7850    }
7851
7852    /**
7853     * Prune any older {@link UriPermission} for the given UID until outstanding
7854     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7855     *
7856     * @return if any mutations occured that require persisting.
7857     */
7858    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7859        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7860        if (perms == null) return false;
7861        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7862
7863        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7864        for (UriPermission perm : perms.values()) {
7865            if (perm.persistedModeFlags != 0) {
7866                persisted.add(perm);
7867            }
7868        }
7869
7870        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7871        if (trimCount <= 0) return false;
7872
7873        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7874        for (int i = 0; i < trimCount; i++) {
7875            final UriPermission perm = persisted.get(i);
7876
7877            if (DEBUG_URI_PERMISSION) {
7878                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7879            }
7880
7881            perm.releasePersistableModes(~0);
7882            removeUriPermissionIfNeededLocked(perm);
7883        }
7884
7885        return true;
7886    }
7887
7888    @Override
7889    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7890            String packageName, boolean incoming) {
7891        enforceNotIsolatedCaller("getPersistedUriPermissions");
7892        Preconditions.checkNotNull(packageName, "packageName");
7893
7894        final int callingUid = Binder.getCallingUid();
7895        final IPackageManager pm = AppGlobals.getPackageManager();
7896        try {
7897            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7898            if (packageUid != callingUid) {
7899                throw new SecurityException(
7900                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7901            }
7902        } catch (RemoteException e) {
7903            throw new SecurityException("Failed to verify package name ownership");
7904        }
7905
7906        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7907        synchronized (this) {
7908            if (incoming) {
7909                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7910                        callingUid);
7911                if (perms == null) {
7912                    Slog.w(TAG, "No permission grants found for " + packageName);
7913                } else {
7914                    for (UriPermission perm : perms.values()) {
7915                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7916                            result.add(perm.buildPersistedPublicApiObject());
7917                        }
7918                    }
7919                }
7920            } else {
7921                final int size = mGrantedUriPermissions.size();
7922                for (int i = 0; i < size; i++) {
7923                    final ArrayMap<GrantUri, UriPermission> perms =
7924                            mGrantedUriPermissions.valueAt(i);
7925                    for (UriPermission perm : perms.values()) {
7926                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7927                            result.add(perm.buildPersistedPublicApiObject());
7928                        }
7929                    }
7930                }
7931            }
7932        }
7933        return new ParceledListSlice<android.content.UriPermission>(result);
7934    }
7935
7936    @Override
7937    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7938        synchronized (this) {
7939            ProcessRecord app =
7940                who != null ? getRecordForAppLocked(who) : null;
7941            if (app == null) return;
7942
7943            Message msg = Message.obtain();
7944            msg.what = WAIT_FOR_DEBUGGER_MSG;
7945            msg.obj = app;
7946            msg.arg1 = waiting ? 1 : 0;
7947            mHandler.sendMessage(msg);
7948        }
7949    }
7950
7951    @Override
7952    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7953        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7954        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7955        outInfo.availMem = Process.getFreeMemory();
7956        outInfo.totalMem = Process.getTotalMemory();
7957        outInfo.threshold = homeAppMem;
7958        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7959        outInfo.hiddenAppThreshold = cachedAppMem;
7960        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7961                ProcessList.SERVICE_ADJ);
7962        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.VISIBLE_APP_ADJ);
7964        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7965                ProcessList.FOREGROUND_APP_ADJ);
7966    }
7967
7968    // =========================================================
7969    // TASK MANAGEMENT
7970    // =========================================================
7971
7972    @Override
7973    public List<IAppTask> getAppTasks(String callingPackage) {
7974        int callingUid = Binder.getCallingUid();
7975        long ident = Binder.clearCallingIdentity();
7976
7977        synchronized(this) {
7978            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7979            try {
7980                if (localLOGV) Slog.v(TAG, "getAppTasks");
7981
7982                final int N = mRecentTasks.size();
7983                for (int i = 0; i < N; i++) {
7984                    TaskRecord tr = mRecentTasks.get(i);
7985                    // Skip tasks that do not match the caller.  We don't need to verify
7986                    // callingPackage, because we are also limiting to callingUid and know
7987                    // that will limit to the correct security sandbox.
7988                    if (tr.effectiveUid != callingUid) {
7989                        continue;
7990                    }
7991                    Intent intent = tr.getBaseIntent();
7992                    if (intent == null ||
7993                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7994                        continue;
7995                    }
7996                    ActivityManager.RecentTaskInfo taskInfo =
7997                            createRecentTaskInfoFromTaskRecord(tr);
7998                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7999                    list.add(taskImpl);
8000                }
8001            } finally {
8002                Binder.restoreCallingIdentity(ident);
8003            }
8004            return list;
8005        }
8006    }
8007
8008    @Override
8009    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8010        final int callingUid = Binder.getCallingUid();
8011        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8012
8013        synchronized(this) {
8014            if (localLOGV) Slog.v(
8015                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8016
8017            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8018                    callingUid);
8019
8020            // TODO: Improve with MRU list from all ActivityStacks.
8021            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8022        }
8023
8024        return list;
8025    }
8026
8027    /**
8028     * Creates a new RecentTaskInfo from a TaskRecord.
8029     */
8030    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8031        // Update the task description to reflect any changes in the task stack
8032        tr.updateTaskDescription();
8033
8034        // Compose the recent task info
8035        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8036        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8037        rti.persistentId = tr.taskId;
8038        rti.baseIntent = new Intent(tr.getBaseIntent());
8039        rti.origActivity = tr.origActivity;
8040        rti.description = tr.lastDescription;
8041        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8042        rti.userId = tr.userId;
8043        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8044        rti.firstActiveTime = tr.firstActiveTime;
8045        rti.lastActiveTime = tr.lastActiveTime;
8046        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8047        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8048        return rti;
8049    }
8050
8051    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8052        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8053                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8054        if (!allowed) {
8055            if (checkPermission(android.Manifest.permission.GET_TASKS,
8056                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8057                // Temporary compatibility: some existing apps on the system image may
8058                // still be requesting the old permission and not switched to the new
8059                // one; if so, we'll still allow them full access.  This means we need
8060                // to see if they are holding the old permission and are a system app.
8061                try {
8062                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8063                        allowed = true;
8064                        Slog.w(TAG, caller + ": caller " + callingUid
8065                                + " is using old GET_TASKS but privileged; allowing");
8066                    }
8067                } catch (RemoteException e) {
8068                }
8069            }
8070        }
8071        if (!allowed) {
8072            Slog.w(TAG, caller + ": caller " + callingUid
8073                    + " does not hold GET_TASKS; limiting output");
8074        }
8075        return allowed;
8076    }
8077
8078    @Override
8079    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8080        final int callingUid = Binder.getCallingUid();
8081        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8082                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8083
8084        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8085        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8086        synchronized (this) {
8087            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8088                    callingUid);
8089            final boolean detailed = checkCallingPermission(
8090                    android.Manifest.permission.GET_DETAILED_TASKS)
8091                    == PackageManager.PERMISSION_GRANTED;
8092
8093            final int N = mRecentTasks.size();
8094            ArrayList<ActivityManager.RecentTaskInfo> res
8095                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8096                            maxNum < N ? maxNum : N);
8097
8098            final Set<Integer> includedUsers;
8099            if (includeProfiles) {
8100                includedUsers = getProfileIdsLocked(userId);
8101            } else {
8102                includedUsers = new HashSet<Integer>();
8103            }
8104            includedUsers.add(Integer.valueOf(userId));
8105
8106            for (int i=0; i<N && maxNum > 0; i++) {
8107                TaskRecord tr = mRecentTasks.get(i);
8108                // Only add calling user or related users recent tasks
8109                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8110                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8111                    continue;
8112                }
8113
8114                // Return the entry if desired by the caller.  We always return
8115                // the first entry, because callers always expect this to be the
8116                // foreground app.  We may filter others if the caller has
8117                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8118                // we should exclude the entry.
8119
8120                if (i == 0
8121                        || withExcluded
8122                        || (tr.intent == null)
8123                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8124                                == 0)) {
8125                    if (!allowed) {
8126                        // If the caller doesn't have the GET_TASKS permission, then only
8127                        // allow them to see a small subset of tasks -- their own and home.
8128                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8129                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8130                            continue;
8131                        }
8132                    }
8133                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8134                        if (tr.stack != null && tr.stack.isHomeStack()) {
8135                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8136                            continue;
8137                        }
8138                    }
8139                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8140                        // Don't include auto remove tasks that are finished or finishing.
8141                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8142                                + tr);
8143                        continue;
8144                    }
8145                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8146                            && !tr.isAvailable) {
8147                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8148                        continue;
8149                    }
8150
8151                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8152                    if (!detailed) {
8153                        rti.baseIntent.replaceExtras((Bundle)null);
8154                    }
8155
8156                    res.add(rti);
8157                    maxNum--;
8158                }
8159            }
8160            return res;
8161        }
8162    }
8163
8164    private TaskRecord taskForIdLocked(int id) {
8165        final TaskRecord task = recentTaskForIdLocked(id);
8166        if (task != null) {
8167            return task;
8168        }
8169
8170        // Don't give up. Sometimes it just hasn't made it to recents yet.
8171        return mStackSupervisor.anyTaskForIdLocked(id);
8172    }
8173
8174    private TaskRecord recentTaskForIdLocked(int id) {
8175        final int N = mRecentTasks.size();
8176            for (int i=0; i<N; i++) {
8177                TaskRecord tr = mRecentTasks.get(i);
8178                if (tr.taskId == id) {
8179                    return tr;
8180                }
8181            }
8182            return null;
8183    }
8184
8185    @Override
8186    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8187        synchronized (this) {
8188            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8189                    "getTaskThumbnail()");
8190            TaskRecord tr = recentTaskForIdLocked(id);
8191            if (tr != null) {
8192                return tr.getTaskThumbnailLocked();
8193            }
8194        }
8195        return null;
8196    }
8197
8198    @Override
8199    public int addAppTask(IBinder activityToken, Intent intent,
8200            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8201        final int callingUid = Binder.getCallingUid();
8202        final long callingIdent = Binder.clearCallingIdentity();
8203
8204        try {
8205            synchronized (this) {
8206                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8207                if (r == null) {
8208                    throw new IllegalArgumentException("Activity does not exist; token="
8209                            + activityToken);
8210                }
8211                ComponentName comp = intent.getComponent();
8212                if (comp == null) {
8213                    throw new IllegalArgumentException("Intent " + intent
8214                            + " must specify explicit component");
8215                }
8216                if (thumbnail.getWidth() != mThumbnailWidth
8217                        || thumbnail.getHeight() != mThumbnailHeight) {
8218                    throw new IllegalArgumentException("Bad thumbnail size: got "
8219                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8220                            + mThumbnailWidth + "x" + mThumbnailHeight);
8221                }
8222                if (intent.getSelector() != null) {
8223                    intent.setSelector(null);
8224                }
8225                if (intent.getSourceBounds() != null) {
8226                    intent.setSourceBounds(null);
8227                }
8228                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8229                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8230                        // The caller has added this as an auto-remove task...  that makes no
8231                        // sense, so turn off auto-remove.
8232                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8233                    }
8234                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8235                    // Must be a new task.
8236                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8237                }
8238                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8239                    mLastAddedTaskActivity = null;
8240                }
8241                ActivityInfo ainfo = mLastAddedTaskActivity;
8242                if (ainfo == null) {
8243                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8244                            comp, 0, UserHandle.getUserId(callingUid));
8245                    if (ainfo.applicationInfo.uid != callingUid) {
8246                        throw new SecurityException(
8247                                "Can't add task for another application: target uid="
8248                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8249                    }
8250                }
8251
8252                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8253                        intent, description);
8254
8255                int trimIdx = trimRecentsForTaskLocked(task, false);
8256                if (trimIdx >= 0) {
8257                    // If this would have caused a trim, then we'll abort because that
8258                    // means it would be added at the end of the list but then just removed.
8259                    return -1;
8260                }
8261
8262                final int N = mRecentTasks.size();
8263                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8264                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8265                    tr.removedFromRecents();
8266                }
8267
8268                task.inRecents = true;
8269                mRecentTasks.add(task);
8270                r.task.stack.addTask(task, false, false);
8271
8272                task.setLastThumbnail(thumbnail);
8273                task.freeLastThumbnail();
8274
8275                return task.taskId;
8276            }
8277        } finally {
8278            Binder.restoreCallingIdentity(callingIdent);
8279        }
8280    }
8281
8282    @Override
8283    public Point getAppTaskThumbnailSize() {
8284        synchronized (this) {
8285            return new Point(mThumbnailWidth,  mThumbnailHeight);
8286        }
8287    }
8288
8289    @Override
8290    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8291        synchronized (this) {
8292            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8293            if (r != null) {
8294                r.setTaskDescription(td);
8295                r.task.updateTaskDescription();
8296            }
8297        }
8298    }
8299
8300    @Override
8301    public Bitmap getTaskDescriptionIcon(String filename) {
8302        if (!FileUtils.isValidExtFilename(filename)
8303                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8304            throw new IllegalArgumentException("Bad filename: " + filename);
8305        }
8306        return mTaskPersister.getTaskDescriptionIcon(filename);
8307    }
8308
8309    @Override
8310    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8311            throws RemoteException {
8312        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8313                opts.getCustomInPlaceResId() == 0) {
8314            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8315                    "with valid animation");
8316        }
8317        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8318        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8319                opts.getCustomInPlaceResId());
8320        mWindowManager.executeAppTransition();
8321    }
8322
8323    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8324        mRecentTasks.remove(tr);
8325        tr.removedFromRecents();
8326        ComponentName component = tr.getBaseIntent().getComponent();
8327        if (component == null) {
8328            Slog.w(TAG, "No component for base intent of task: " + tr);
8329            return;
8330        }
8331
8332        if (!killProcess) {
8333            return;
8334        }
8335
8336        // Determine if the process(es) for this task should be killed.
8337        final String pkg = component.getPackageName();
8338        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8339        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8340        for (int i = 0; i < pmap.size(); i++) {
8341
8342            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8343            for (int j = 0; j < uids.size(); j++) {
8344                ProcessRecord proc = uids.valueAt(j);
8345                if (proc.userId != tr.userId) {
8346                    // Don't kill process for a different user.
8347                    continue;
8348                }
8349                if (proc == mHomeProcess) {
8350                    // Don't kill the home process along with tasks from the same package.
8351                    continue;
8352                }
8353                if (!proc.pkgList.containsKey(pkg)) {
8354                    // Don't kill process that is not associated with this task.
8355                    continue;
8356                }
8357
8358                for (int k = 0; k < proc.activities.size(); k++) {
8359                    TaskRecord otherTask = proc.activities.get(k).task;
8360                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8361                        // Don't kill process(es) that has an activity in a different task that is
8362                        // also in recents.
8363                        return;
8364                    }
8365                }
8366
8367                // Add process to kill list.
8368                procsToKill.add(proc);
8369            }
8370        }
8371
8372        // Find any running services associated with this app and stop if needed.
8373        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8374
8375        // Kill the running processes.
8376        for (int i = 0; i < procsToKill.size(); i++) {
8377            ProcessRecord pr = procsToKill.get(i);
8378            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8379                pr.kill("remove task", true);
8380            } else {
8381                pr.waitingToKill = "remove task";
8382            }
8383        }
8384    }
8385
8386    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8387        // Remove all tasks with activities in the specified package from the list of recent tasks
8388        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8389            TaskRecord tr = mRecentTasks.get(i);
8390            if (tr.userId != userId) continue;
8391
8392            ComponentName cn = tr.intent.getComponent();
8393            if (cn != null && cn.getPackageName().equals(packageName)) {
8394                // If the package name matches, remove the task.
8395                removeTaskByIdLocked(tr.taskId, true);
8396            }
8397        }
8398    }
8399
8400    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8401        final IPackageManager pm = AppGlobals.getPackageManager();
8402        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8403
8404        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8405            TaskRecord tr = mRecentTasks.get(i);
8406            if (tr.userId != userId) continue;
8407
8408            ComponentName cn = tr.intent.getComponent();
8409            if (cn != null && cn.getPackageName().equals(packageName)) {
8410                // Skip if component still exists in the package.
8411                if (componentsKnownToExist.contains(cn)) continue;
8412
8413                try {
8414                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8415                    if (info != null) {
8416                        componentsKnownToExist.add(cn);
8417                    } else {
8418                        removeTaskByIdLocked(tr.taskId, false);
8419                    }
8420                } catch (RemoteException e) {
8421                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8422                }
8423            }
8424        }
8425    }
8426
8427    /**
8428     * Removes the task with the specified task id.
8429     *
8430     * @param taskId Identifier of the task to be removed.
8431     * @param killProcess Kill any process associated with the task if possible.
8432     * @return Returns true if the given task was found and removed.
8433     */
8434    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8435        TaskRecord tr = taskForIdLocked(taskId);
8436        if (tr != null) {
8437            tr.removeTaskActivitiesLocked();
8438            cleanUpRemovedTaskLocked(tr, killProcess);
8439            if (tr.isPersistable) {
8440                notifyTaskPersisterLocked(null, true);
8441            }
8442            return true;
8443        }
8444        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8445        return false;
8446    }
8447
8448    @Override
8449    public boolean removeTask(int taskId) {
8450        synchronized (this) {
8451            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8452                    "removeTask()");
8453            long ident = Binder.clearCallingIdentity();
8454            try {
8455                return removeTaskByIdLocked(taskId, true);
8456            } finally {
8457                Binder.restoreCallingIdentity(ident);
8458            }
8459        }
8460    }
8461
8462    /**
8463     * TODO: Add mController hook
8464     */
8465    @Override
8466    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8467        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8468                "moveTaskToFront()");
8469
8470        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8471        synchronized(this) {
8472            moveTaskToFrontLocked(taskId, flags, options);
8473        }
8474    }
8475
8476    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8477        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8478                Binder.getCallingUid(), -1, -1, "Task to front")) {
8479            ActivityOptions.abort(options);
8480            return;
8481        }
8482        final long origId = Binder.clearCallingIdentity();
8483        try {
8484            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8485            if (task == null) {
8486                Slog.d(TAG, "Could not find task for id: "+ taskId);
8487                return;
8488            }
8489            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8490                mStackSupervisor.showLockTaskToast();
8491                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8492                return;
8493            }
8494            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8495            if (prev != null && prev.isRecentsActivity()) {
8496                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8497            }
8498            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8499        } finally {
8500            Binder.restoreCallingIdentity(origId);
8501        }
8502        ActivityOptions.abort(options);
8503    }
8504
8505    @Override
8506    public void moveTaskToBack(int taskId) {
8507        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8508                "moveTaskToBack()");
8509
8510        synchronized(this) {
8511            TaskRecord tr = taskForIdLocked(taskId);
8512            if (tr != null) {
8513                if (tr == mStackSupervisor.mLockTaskModeTask) {
8514                    mStackSupervisor.showLockTaskToast();
8515                    return;
8516                }
8517                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8518                ActivityStack stack = tr.stack;
8519                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8520                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8521                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8522                        return;
8523                    }
8524                }
8525                final long origId = Binder.clearCallingIdentity();
8526                try {
8527                    stack.moveTaskToBackLocked(taskId, null);
8528                } finally {
8529                    Binder.restoreCallingIdentity(origId);
8530                }
8531            }
8532        }
8533    }
8534
8535    /**
8536     * Moves an activity, and all of the other activities within the same task, to the bottom
8537     * of the history stack.  The activity's order within the task is unchanged.
8538     *
8539     * @param token A reference to the activity we wish to move
8540     * @param nonRoot If false then this only works if the activity is the root
8541     *                of a task; if true it will work for any activity in a task.
8542     * @return Returns true if the move completed, false if not.
8543     */
8544    @Override
8545    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8546        enforceNotIsolatedCaller("moveActivityTaskToBack");
8547        synchronized(this) {
8548            final long origId = Binder.clearCallingIdentity();
8549            try {
8550                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8551                if (taskId >= 0) {
8552                    if ((mStackSupervisor.mLockTaskModeTask != null)
8553                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8554                        mStackSupervisor.showLockTaskToast();
8555                        return false;
8556                    }
8557                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8558                }
8559            } finally {
8560                Binder.restoreCallingIdentity(origId);
8561            }
8562        }
8563        return false;
8564    }
8565
8566    @Override
8567    public void moveTaskBackwards(int task) {
8568        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8569                "moveTaskBackwards()");
8570
8571        synchronized(this) {
8572            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8573                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8574                return;
8575            }
8576            final long origId = Binder.clearCallingIdentity();
8577            moveTaskBackwardsLocked(task);
8578            Binder.restoreCallingIdentity(origId);
8579        }
8580    }
8581
8582    private final void moveTaskBackwardsLocked(int task) {
8583        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8584    }
8585
8586    @Override
8587    public IBinder getHomeActivityToken() throws RemoteException {
8588        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8589                "getHomeActivityToken()");
8590        synchronized (this) {
8591            return mStackSupervisor.getHomeActivityToken();
8592        }
8593    }
8594
8595    @Override
8596    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8597            IActivityContainerCallback callback) throws RemoteException {
8598        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8599                "createActivityContainer()");
8600        synchronized (this) {
8601            if (parentActivityToken == null) {
8602                throw new IllegalArgumentException("parent token must not be null");
8603            }
8604            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8605            if (r == null) {
8606                return null;
8607            }
8608            if (callback == null) {
8609                throw new IllegalArgumentException("callback must not be null");
8610            }
8611            return mStackSupervisor.createActivityContainer(r, callback);
8612        }
8613    }
8614
8615    @Override
8616    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8618                "deleteActivityContainer()");
8619        synchronized (this) {
8620            mStackSupervisor.deleteActivityContainer(container);
8621        }
8622    }
8623
8624    @Override
8625    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8626            throws RemoteException {
8627        synchronized (this) {
8628            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8629            if (stack != null) {
8630                return stack.mActivityContainer;
8631            }
8632            return null;
8633        }
8634    }
8635
8636    @Override
8637    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8638        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8639                "moveTaskToStack()");
8640        if (stackId == HOME_STACK_ID) {
8641            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8642                    new RuntimeException("here").fillInStackTrace());
8643        }
8644        synchronized (this) {
8645            long ident = Binder.clearCallingIdentity();
8646            try {
8647                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8648                        + stackId + " toTop=" + toTop);
8649                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8650            } finally {
8651                Binder.restoreCallingIdentity(ident);
8652            }
8653        }
8654    }
8655
8656    @Override
8657    public void resizeStack(int stackBoxId, Rect bounds) {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "resizeStackBox()");
8660        long ident = Binder.clearCallingIdentity();
8661        try {
8662            mWindowManager.resizeStack(stackBoxId, bounds);
8663        } finally {
8664            Binder.restoreCallingIdentity(ident);
8665        }
8666    }
8667
8668    @Override
8669    public List<StackInfo> getAllStackInfos() {
8670        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8671                "getAllStackInfos()");
8672        long ident = Binder.clearCallingIdentity();
8673        try {
8674            synchronized (this) {
8675                return mStackSupervisor.getAllStackInfosLocked();
8676            }
8677        } finally {
8678            Binder.restoreCallingIdentity(ident);
8679        }
8680    }
8681
8682    @Override
8683    public StackInfo getStackInfo(int stackId) {
8684        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8685                "getStackInfo()");
8686        long ident = Binder.clearCallingIdentity();
8687        try {
8688            synchronized (this) {
8689                return mStackSupervisor.getStackInfoLocked(stackId);
8690            }
8691        } finally {
8692            Binder.restoreCallingIdentity(ident);
8693        }
8694    }
8695
8696    @Override
8697    public boolean isInHomeStack(int taskId) {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "getStackInfo()");
8700        long ident = Binder.clearCallingIdentity();
8701        try {
8702            synchronized (this) {
8703                TaskRecord tr = taskForIdLocked(taskId);
8704                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8705            }
8706        } finally {
8707            Binder.restoreCallingIdentity(ident);
8708        }
8709    }
8710
8711    @Override
8712    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8713        synchronized(this) {
8714            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8715        }
8716    }
8717
8718    private boolean isLockTaskAuthorized(String pkg) {
8719        final DevicePolicyManager dpm = (DevicePolicyManager)
8720                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8721        try {
8722            int uid = mContext.getPackageManager().getPackageUid(pkg,
8723                    Binder.getCallingUserHandle().getIdentifier());
8724            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8725        } catch (NameNotFoundException e) {
8726            return false;
8727        }
8728    }
8729
8730    void startLockTaskMode(TaskRecord task) {
8731        final String pkg;
8732        synchronized (this) {
8733            pkg = task.intent.getComponent().getPackageName();
8734        }
8735        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8736        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8737            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8738                    StatusBarManagerInternal.class);
8739            if (statusBarManager != null) {
8740                statusBarManager.showScreenPinningRequest();
8741            }
8742            return;
8743        }
8744        long ident = Binder.clearCallingIdentity();
8745        try {
8746            synchronized (this) {
8747                // Since we lost lock on task, make sure it is still there.
8748                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8749                if (task != null) {
8750                    if (!isSystemInitiated
8751                            && ((mStackSupervisor.getFocusedStack() == null)
8752                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8753                        throw new IllegalArgumentException("Invalid task, not in foreground");
8754                    }
8755                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8756                }
8757            }
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public void startLockTaskMode(int taskId) {
8765        final TaskRecord task;
8766        long ident = Binder.clearCallingIdentity();
8767        try {
8768            synchronized (this) {
8769                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8770            }
8771        } finally {
8772            Binder.restoreCallingIdentity(ident);
8773        }
8774        if (task != null) {
8775            startLockTaskMode(task);
8776        }
8777    }
8778
8779    @Override
8780    public void startLockTaskMode(IBinder token) {
8781        final TaskRecord task;
8782        long ident = Binder.clearCallingIdentity();
8783        try {
8784            synchronized (this) {
8785                final ActivityRecord r = ActivityRecord.forToken(token);
8786                if (r == null) {
8787                    return;
8788                }
8789                task = r.task;
8790            }
8791        } finally {
8792            Binder.restoreCallingIdentity(ident);
8793        }
8794        if (task != null) {
8795            startLockTaskMode(task);
8796        }
8797    }
8798
8799    @Override
8800    public void startLockTaskModeOnCurrent() throws RemoteException {
8801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8802                "startLockTaskModeOnCurrent");
8803        long ident = Binder.clearCallingIdentity();
8804        try {
8805            ActivityRecord r = null;
8806            synchronized (this) {
8807                r = mStackSupervisor.topRunningActivityLocked();
8808            }
8809            startLockTaskMode(r.task);
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813    }
8814
8815    @Override
8816    public void stopLockTaskMode() {
8817        // Verify that the user matches the package of the intent for the TaskRecord
8818        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8819        // and stopLockTaskMode.
8820        final int callingUid = Binder.getCallingUid();
8821        if (callingUid != Process.SYSTEM_UID) {
8822            try {
8823                String pkg =
8824                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8825                int uid = mContext.getPackageManager().getPackageUid(pkg,
8826                        Binder.getCallingUserHandle().getIdentifier());
8827                if (uid != callingUid) {
8828                    throw new SecurityException("Invalid uid, expected " + uid);
8829                }
8830            } catch (NameNotFoundException e) {
8831                Log.d(TAG, "stopLockTaskMode " + e);
8832                return;
8833            }
8834        }
8835        long ident = Binder.clearCallingIdentity();
8836        try {
8837            Log.d(TAG, "stopLockTaskMode");
8838            // Stop lock task
8839            synchronized (this) {
8840                mStackSupervisor.setLockTaskModeLocked(null, false);
8841            }
8842        } finally {
8843            Binder.restoreCallingIdentity(ident);
8844        }
8845    }
8846
8847    @Override
8848    public void stopLockTaskModeOnCurrent() throws RemoteException {
8849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8850                "stopLockTaskModeOnCurrent");
8851        long ident = Binder.clearCallingIdentity();
8852        try {
8853            stopLockTaskMode();
8854        } finally {
8855            Binder.restoreCallingIdentity(ident);
8856        }
8857    }
8858
8859    @Override
8860    public boolean isInLockTaskMode() {
8861        synchronized (this) {
8862            return mStackSupervisor.isInLockTaskMode();
8863        }
8864    }
8865
8866    // =========================================================
8867    // CONTENT PROVIDERS
8868    // =========================================================
8869
8870    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8871        List<ProviderInfo> providers = null;
8872        try {
8873            providers = AppGlobals.getPackageManager().
8874                queryContentProviders(app.processName, app.uid,
8875                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8876        } catch (RemoteException ex) {
8877        }
8878        if (DEBUG_MU)
8879            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8880        int userId = app.userId;
8881        if (providers != null) {
8882            int N = providers.size();
8883            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8884            for (int i=0; i<N; i++) {
8885                ProviderInfo cpi =
8886                    (ProviderInfo)providers.get(i);
8887                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8888                        cpi.name, cpi.flags);
8889                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8890                    // This is a singleton provider, but a user besides the
8891                    // default user is asking to initialize a process it runs
8892                    // in...  well, no, it doesn't actually run in this process,
8893                    // it runs in the process of the default user.  Get rid of it.
8894                    providers.remove(i);
8895                    N--;
8896                    i--;
8897                    continue;
8898                }
8899
8900                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8901                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8902                if (cpr == null) {
8903                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8904                    mProviderMap.putProviderByClass(comp, cpr);
8905                }
8906                if (DEBUG_MU)
8907                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8908                app.pubProviders.put(cpi.name, cpr);
8909                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8910                    // Don't add this if it is a platform component that is marked
8911                    // to run in multiple processes, because this is actually
8912                    // part of the framework so doesn't make sense to track as a
8913                    // separate apk in the process.
8914                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8915                            mProcessStats);
8916                }
8917                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8918            }
8919        }
8920        return providers;
8921    }
8922
8923    /**
8924     * Check if {@link ProcessRecord} has a possible chance at accessing the
8925     * given {@link ProviderInfo}. Final permission checking is always done
8926     * in {@link ContentProvider}.
8927     */
8928    private final String checkContentProviderPermissionLocked(
8929            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8930        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8931        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8932        boolean checkedGrants = false;
8933        if (checkUser) {
8934            // Looking for cross-user grants before enforcing the typical cross-users permissions
8935            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8936            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8937                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8938                    return null;
8939                }
8940                checkedGrants = true;
8941            }
8942            userId = handleIncomingUser(callingPid, callingUid, userId,
8943                    false, ALLOW_NON_FULL,
8944                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8945            if (userId != tmpTargetUserId) {
8946                // When we actually went to determine the final targer user ID, this ended
8947                // up different than our initial check for the authority.  This is because
8948                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8949                // SELF.  So we need to re-check the grants again.
8950                checkedGrants = false;
8951            }
8952        }
8953        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8954                cpi.applicationInfo.uid, cpi.exported)
8955                == PackageManager.PERMISSION_GRANTED) {
8956            return null;
8957        }
8958        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8959                cpi.applicationInfo.uid, cpi.exported)
8960                == PackageManager.PERMISSION_GRANTED) {
8961            return null;
8962        }
8963
8964        PathPermission[] pps = cpi.pathPermissions;
8965        if (pps != null) {
8966            int i = pps.length;
8967            while (i > 0) {
8968                i--;
8969                PathPermission pp = pps[i];
8970                String pprperm = pp.getReadPermission();
8971                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8972                        cpi.applicationInfo.uid, cpi.exported)
8973                        == PackageManager.PERMISSION_GRANTED) {
8974                    return null;
8975                }
8976                String ppwperm = pp.getWritePermission();
8977                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8978                        cpi.applicationInfo.uid, cpi.exported)
8979                        == PackageManager.PERMISSION_GRANTED) {
8980                    return null;
8981                }
8982            }
8983        }
8984        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8985            return null;
8986        }
8987
8988        String msg;
8989        if (!cpi.exported) {
8990            msg = "Permission Denial: opening provider " + cpi.name
8991                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8992                    + ", uid=" + callingUid + ") that is not exported from uid "
8993                    + cpi.applicationInfo.uid;
8994        } else {
8995            msg = "Permission Denial: opening provider " + cpi.name
8996                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8997                    + ", uid=" + callingUid + ") requires "
8998                    + cpi.readPermission + " or " + cpi.writePermission;
8999        }
9000        Slog.w(TAG, msg);
9001        return msg;
9002    }
9003
9004    /**
9005     * Returns if the ContentProvider has granted a uri to callingUid
9006     */
9007    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9008        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9009        if (perms != null) {
9010            for (int i=perms.size()-1; i>=0; i--) {
9011                GrantUri grantUri = perms.keyAt(i);
9012                if (grantUri.sourceUserId == userId || !checkUser) {
9013                    if (matchesProvider(grantUri.uri, cpi)) {
9014                        return true;
9015                    }
9016                }
9017            }
9018        }
9019        return false;
9020    }
9021
9022    /**
9023     * Returns true if the uri authority is one of the authorities specified in the provider.
9024     */
9025    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9026        String uriAuth = uri.getAuthority();
9027        String cpiAuth = cpi.authority;
9028        if (cpiAuth.indexOf(';') == -1) {
9029            return cpiAuth.equals(uriAuth);
9030        }
9031        String[] cpiAuths = cpiAuth.split(";");
9032        int length = cpiAuths.length;
9033        for (int i = 0; i < length; i++) {
9034            if (cpiAuths[i].equals(uriAuth)) return true;
9035        }
9036        return false;
9037    }
9038
9039    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9040            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9041        if (r != null) {
9042            for (int i=0; i<r.conProviders.size(); i++) {
9043                ContentProviderConnection conn = r.conProviders.get(i);
9044                if (conn.provider == cpr) {
9045                    if (DEBUG_PROVIDER) Slog.v(TAG,
9046                            "Adding provider requested by "
9047                            + r.processName + " from process "
9048                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9049                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9050                    if (stable) {
9051                        conn.stableCount++;
9052                        conn.numStableIncs++;
9053                    } else {
9054                        conn.unstableCount++;
9055                        conn.numUnstableIncs++;
9056                    }
9057                    return conn;
9058                }
9059            }
9060            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9061            if (stable) {
9062                conn.stableCount = 1;
9063                conn.numStableIncs = 1;
9064            } else {
9065                conn.unstableCount = 1;
9066                conn.numUnstableIncs = 1;
9067            }
9068            cpr.connections.add(conn);
9069            r.conProviders.add(conn);
9070            return conn;
9071        }
9072        cpr.addExternalProcessHandleLocked(externalProcessToken);
9073        return null;
9074    }
9075
9076    boolean decProviderCountLocked(ContentProviderConnection conn,
9077            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9078        if (conn != null) {
9079            cpr = conn.provider;
9080            if (DEBUG_PROVIDER) Slog.v(TAG,
9081                    "Removing provider requested by "
9082                    + conn.client.processName + " from process "
9083                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9084                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9085            if (stable) {
9086                conn.stableCount--;
9087            } else {
9088                conn.unstableCount--;
9089            }
9090            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9091                cpr.connections.remove(conn);
9092                conn.client.conProviders.remove(conn);
9093                return true;
9094            }
9095            return false;
9096        }
9097        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9098        return false;
9099    }
9100
9101    private void checkTime(long startTime, String where) {
9102        long now = SystemClock.elapsedRealtime();
9103        if ((now-startTime) > 1000) {
9104            // If we are taking more than a second, log about it.
9105            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9106        }
9107    }
9108
9109    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9110            String name, IBinder token, boolean stable, int userId) {
9111        ContentProviderRecord cpr;
9112        ContentProviderConnection conn = null;
9113        ProviderInfo cpi = null;
9114
9115        synchronized(this) {
9116            long startTime = SystemClock.elapsedRealtime();
9117
9118            ProcessRecord r = null;
9119            if (caller != null) {
9120                r = getRecordForAppLocked(caller);
9121                if (r == null) {
9122                    throw new SecurityException(
9123                            "Unable to find app for caller " + caller
9124                          + " (pid=" + Binder.getCallingPid()
9125                          + ") when getting content provider " + name);
9126                }
9127            }
9128
9129            boolean checkCrossUser = true;
9130
9131            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9132
9133            // First check if this content provider has been published...
9134            cpr = mProviderMap.getProviderByName(name, userId);
9135            // If that didn't work, check if it exists for user 0 and then
9136            // verify that it's a singleton provider before using it.
9137            if (cpr == null && userId != UserHandle.USER_OWNER) {
9138                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9139                if (cpr != null) {
9140                    cpi = cpr.info;
9141                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9142                            cpi.name, cpi.flags)
9143                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9144                        userId = UserHandle.USER_OWNER;
9145                        checkCrossUser = false;
9146                    } else {
9147                        cpr = null;
9148                        cpi = null;
9149                    }
9150                }
9151            }
9152
9153            boolean providerRunning = cpr != null;
9154            if (providerRunning) {
9155                cpi = cpr.info;
9156                String msg;
9157                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9158                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9159                        != null) {
9160                    throw new SecurityException(msg);
9161                }
9162                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9163
9164                if (r != null && cpr.canRunHere(r)) {
9165                    // This provider has been published or is in the process
9166                    // of being published...  but it is also allowed to run
9167                    // in the caller's process, so don't make a connection
9168                    // and just let the caller instantiate its own instance.
9169                    ContentProviderHolder holder = cpr.newHolder(null);
9170                    // don't give caller the provider object, it needs
9171                    // to make its own.
9172                    holder.provider = null;
9173                    return holder;
9174                }
9175
9176                final long origId = Binder.clearCallingIdentity();
9177
9178                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9179
9180                // In this case the provider instance already exists, so we can
9181                // return it right away.
9182                conn = incProviderCountLocked(r, cpr, token, stable);
9183                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9184                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9185                        // If this is a perceptible app accessing the provider,
9186                        // make sure to count it as being accessed and thus
9187                        // back up on the LRU list.  This is good because
9188                        // content providers are often expensive to start.
9189                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9190                        updateLruProcessLocked(cpr.proc, false, null);
9191                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9192                    }
9193                }
9194
9195                if (cpr.proc != null) {
9196                    if (false) {
9197                        if (cpr.name.flattenToShortString().equals(
9198                                "com.android.providers.calendar/.CalendarProvider2")) {
9199                            Slog.v(TAG, "****************** KILLING "
9200                                + cpr.name.flattenToShortString());
9201                            Process.killProcess(cpr.proc.pid);
9202                        }
9203                    }
9204                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9205                    boolean success = updateOomAdjLocked(cpr.proc);
9206                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9207                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9208                    // NOTE: there is still a race here where a signal could be
9209                    // pending on the process even though we managed to update its
9210                    // adj level.  Not sure what to do about this, but at least
9211                    // the race is now smaller.
9212                    if (!success) {
9213                        // Uh oh...  it looks like the provider's process
9214                        // has been killed on us.  We need to wait for a new
9215                        // process to be started, and make sure its death
9216                        // doesn't kill our process.
9217                        Slog.i(TAG,
9218                                "Existing provider " + cpr.name.flattenToShortString()
9219                                + " is crashing; detaching " + r);
9220                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9221                        checkTime(startTime, "getContentProviderImpl: before appDied");
9222                        appDiedLocked(cpr.proc);
9223                        checkTime(startTime, "getContentProviderImpl: after appDied");
9224                        if (!lastRef) {
9225                            // This wasn't the last ref our process had on
9226                            // the provider...  we have now been killed, bail.
9227                            return null;
9228                        }
9229                        providerRunning = false;
9230                        conn = null;
9231                    }
9232                }
9233
9234                Binder.restoreCallingIdentity(origId);
9235            }
9236
9237            boolean singleton;
9238            if (!providerRunning) {
9239                try {
9240                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9241                    cpi = AppGlobals.getPackageManager().
9242                        resolveContentProvider(name,
9243                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9244                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9245                } catch (RemoteException ex) {
9246                }
9247                if (cpi == null) {
9248                    return null;
9249                }
9250                // If the provider is a singleton AND
9251                // (it's a call within the same user || the provider is a
9252                // privileged app)
9253                // Then allow connecting to the singleton provider
9254                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9255                        cpi.name, cpi.flags)
9256                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9257                if (singleton) {
9258                    userId = UserHandle.USER_OWNER;
9259                }
9260                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9261                checkTime(startTime, "getContentProviderImpl: got app info for user");
9262
9263                String msg;
9264                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9265                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9266                        != null) {
9267                    throw new SecurityException(msg);
9268                }
9269                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9270
9271                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9272                        && !cpi.processName.equals("system")) {
9273                    // If this content provider does not run in the system
9274                    // process, and the system is not yet ready to run other
9275                    // processes, then fail fast instead of hanging.
9276                    throw new IllegalArgumentException(
9277                            "Attempt to launch content provider before system ready");
9278                }
9279
9280                // Make sure that the user who owns this provider is started.  If not,
9281                // we don't want to allow it to run.
9282                if (mStartedUsers.get(userId) == null) {
9283                    Slog.w(TAG, "Unable to launch app "
9284                            + cpi.applicationInfo.packageName + "/"
9285                            + cpi.applicationInfo.uid + " for provider "
9286                            + name + ": user " + userId + " is stopped");
9287                    return null;
9288                }
9289
9290                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9291                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9292                cpr = mProviderMap.getProviderByClass(comp, userId);
9293                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9294                final boolean firstClass = cpr == null;
9295                if (firstClass) {
9296                    final long ident = Binder.clearCallingIdentity();
9297                    try {
9298                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9299                        ApplicationInfo ai =
9300                            AppGlobals.getPackageManager().
9301                                getApplicationInfo(
9302                                        cpi.applicationInfo.packageName,
9303                                        STOCK_PM_FLAGS, userId);
9304                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9305                        if (ai == null) {
9306                            Slog.w(TAG, "No package info for content provider "
9307                                    + cpi.name);
9308                            return null;
9309                        }
9310                        ai = getAppInfoForUser(ai, userId);
9311                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9312                    } catch (RemoteException ex) {
9313                        // pm is in same process, this will never happen.
9314                    } finally {
9315                        Binder.restoreCallingIdentity(ident);
9316                    }
9317                }
9318
9319                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9320
9321                if (r != null && cpr.canRunHere(r)) {
9322                    // If this is a multiprocess provider, then just return its
9323                    // info and allow the caller to instantiate it.  Only do
9324                    // this if the provider is the same user as the caller's
9325                    // process, or can run as root (so can be in any process).
9326                    return cpr.newHolder(null);
9327                }
9328
9329                if (DEBUG_PROVIDER) {
9330                    RuntimeException e = new RuntimeException("here");
9331                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9332                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9333                }
9334
9335                // This is single process, and our app is now connecting to it.
9336                // See if we are already in the process of launching this
9337                // provider.
9338                final int N = mLaunchingProviders.size();
9339                int i;
9340                for (i=0; i<N; i++) {
9341                    if (mLaunchingProviders.get(i) == cpr) {
9342                        break;
9343                    }
9344                }
9345
9346                // If the provider is not already being launched, then get it
9347                // started.
9348                if (i >= N) {
9349                    final long origId = Binder.clearCallingIdentity();
9350
9351                    try {
9352                        // Content provider is now in use, its package can't be stopped.
9353                        try {
9354                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9355                            AppGlobals.getPackageManager().setPackageStoppedState(
9356                                    cpr.appInfo.packageName, false, userId);
9357                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9358                        } catch (RemoteException e) {
9359                        } catch (IllegalArgumentException e) {
9360                            Slog.w(TAG, "Failed trying to unstop package "
9361                                    + cpr.appInfo.packageName + ": " + e);
9362                        }
9363
9364                        // Use existing process if already started
9365                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9366                        ProcessRecord proc = getProcessRecordLocked(
9367                                cpi.processName, cpr.appInfo.uid, false);
9368                        if (proc != null && proc.thread != null) {
9369                            if (DEBUG_PROVIDER) {
9370                                Slog.d(TAG, "Installing in existing process " + proc);
9371                            }
9372                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9373                            proc.pubProviders.put(cpi.name, cpr);
9374                            try {
9375                                proc.thread.scheduleInstallProvider(cpi);
9376                            } catch (RemoteException e) {
9377                            }
9378                        } else {
9379                            checkTime(startTime, "getContentProviderImpl: before start process");
9380                            proc = startProcessLocked(cpi.processName,
9381                                    cpr.appInfo, false, 0, "content provider",
9382                                    new ComponentName(cpi.applicationInfo.packageName,
9383                                            cpi.name), false, false, false);
9384                            checkTime(startTime, "getContentProviderImpl: after start process");
9385                            if (proc == null) {
9386                                Slog.w(TAG, "Unable to launch app "
9387                                        + cpi.applicationInfo.packageName + "/"
9388                                        + cpi.applicationInfo.uid + " for provider "
9389                                        + name + ": process is bad");
9390                                return null;
9391                            }
9392                        }
9393                        cpr.launchingApp = proc;
9394                        mLaunchingProviders.add(cpr);
9395                    } finally {
9396                        Binder.restoreCallingIdentity(origId);
9397                    }
9398                }
9399
9400                checkTime(startTime, "getContentProviderImpl: updating data structures");
9401
9402                // Make sure the provider is published (the same provider class
9403                // may be published under multiple names).
9404                if (firstClass) {
9405                    mProviderMap.putProviderByClass(comp, cpr);
9406                }
9407
9408                mProviderMap.putProviderByName(name, cpr);
9409                conn = incProviderCountLocked(r, cpr, token, stable);
9410                if (conn != null) {
9411                    conn.waiting = true;
9412                }
9413            }
9414            checkTime(startTime, "getContentProviderImpl: done!");
9415        }
9416
9417        // Wait for the provider to be published...
9418        synchronized (cpr) {
9419            while (cpr.provider == null) {
9420                if (cpr.launchingApp == null) {
9421                    Slog.w(TAG, "Unable to launch app "
9422                            + cpi.applicationInfo.packageName + "/"
9423                            + cpi.applicationInfo.uid + " for provider "
9424                            + name + ": launching app became null");
9425                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9426                            UserHandle.getUserId(cpi.applicationInfo.uid),
9427                            cpi.applicationInfo.packageName,
9428                            cpi.applicationInfo.uid, name);
9429                    return null;
9430                }
9431                try {
9432                    if (DEBUG_MU) {
9433                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9434                                + cpr.launchingApp);
9435                    }
9436                    if (conn != null) {
9437                        conn.waiting = true;
9438                    }
9439                    cpr.wait();
9440                } catch (InterruptedException ex) {
9441                } finally {
9442                    if (conn != null) {
9443                        conn.waiting = false;
9444                    }
9445                }
9446            }
9447        }
9448        return cpr != null ? cpr.newHolder(conn) : null;
9449    }
9450
9451    @Override
9452    public final ContentProviderHolder getContentProvider(
9453            IApplicationThread caller, String name, int userId, boolean stable) {
9454        enforceNotIsolatedCaller("getContentProvider");
9455        if (caller == null) {
9456            String msg = "null IApplicationThread when getting content provider "
9457                    + name;
9458            Slog.w(TAG, msg);
9459            throw new SecurityException(msg);
9460        }
9461        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9462        // with cross-user grant.
9463        return getContentProviderImpl(caller, name, null, stable, userId);
9464    }
9465
9466    public ContentProviderHolder getContentProviderExternal(
9467            String name, int userId, IBinder token) {
9468        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9469            "Do not have permission in call getContentProviderExternal()");
9470        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9471                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9472        return getContentProviderExternalUnchecked(name, token, userId);
9473    }
9474
9475    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9476            IBinder token, int userId) {
9477        return getContentProviderImpl(null, name, token, true, userId);
9478    }
9479
9480    /**
9481     * Drop a content provider from a ProcessRecord's bookkeeping
9482     */
9483    public void removeContentProvider(IBinder connection, boolean stable) {
9484        enforceNotIsolatedCaller("removeContentProvider");
9485        long ident = Binder.clearCallingIdentity();
9486        try {
9487            synchronized (this) {
9488                ContentProviderConnection conn;
9489                try {
9490                    conn = (ContentProviderConnection)connection;
9491                } catch (ClassCastException e) {
9492                    String msg ="removeContentProvider: " + connection
9493                            + " not a ContentProviderConnection";
9494                    Slog.w(TAG, msg);
9495                    throw new IllegalArgumentException(msg);
9496                }
9497                if (conn == null) {
9498                    throw new NullPointerException("connection is null");
9499                }
9500                if (decProviderCountLocked(conn, null, null, stable)) {
9501                    updateOomAdjLocked();
9502                }
9503            }
9504        } finally {
9505            Binder.restoreCallingIdentity(ident);
9506        }
9507    }
9508
9509    public void removeContentProviderExternal(String name, IBinder token) {
9510        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9511            "Do not have permission in call removeContentProviderExternal()");
9512        int userId = UserHandle.getCallingUserId();
9513        long ident = Binder.clearCallingIdentity();
9514        try {
9515            removeContentProviderExternalUnchecked(name, token, userId);
9516        } finally {
9517            Binder.restoreCallingIdentity(ident);
9518        }
9519    }
9520
9521    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9522        synchronized (this) {
9523            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9524            if(cpr == null) {
9525                //remove from mProvidersByClass
9526                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9527                return;
9528            }
9529
9530            //update content provider record entry info
9531            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9532            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9533            if (localCpr.hasExternalProcessHandles()) {
9534                if (localCpr.removeExternalProcessHandleLocked(token)) {
9535                    updateOomAdjLocked();
9536                } else {
9537                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9538                            + " with no external reference for token: "
9539                            + token + ".");
9540                }
9541            } else {
9542                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9543                        + " with no external references.");
9544            }
9545        }
9546    }
9547
9548    public final void publishContentProviders(IApplicationThread caller,
9549            List<ContentProviderHolder> providers) {
9550        if (providers == null) {
9551            return;
9552        }
9553
9554        enforceNotIsolatedCaller("publishContentProviders");
9555        synchronized (this) {
9556            final ProcessRecord r = getRecordForAppLocked(caller);
9557            if (DEBUG_MU)
9558                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9559            if (r == null) {
9560                throw new SecurityException(
9561                        "Unable to find app for caller " + caller
9562                      + " (pid=" + Binder.getCallingPid()
9563                      + ") when publishing content providers");
9564            }
9565
9566            final long origId = Binder.clearCallingIdentity();
9567
9568            final int N = providers.size();
9569            for (int i=0; i<N; i++) {
9570                ContentProviderHolder src = providers.get(i);
9571                if (src == null || src.info == null || src.provider == null) {
9572                    continue;
9573                }
9574                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9575                if (DEBUG_MU)
9576                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9577                if (dst != null) {
9578                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9579                    mProviderMap.putProviderByClass(comp, dst);
9580                    String names[] = dst.info.authority.split(";");
9581                    for (int j = 0; j < names.length; j++) {
9582                        mProviderMap.putProviderByName(names[j], dst);
9583                    }
9584
9585                    int NL = mLaunchingProviders.size();
9586                    int j;
9587                    for (j=0; j<NL; j++) {
9588                        if (mLaunchingProviders.get(j) == dst) {
9589                            mLaunchingProviders.remove(j);
9590                            j--;
9591                            NL--;
9592                        }
9593                    }
9594                    synchronized (dst) {
9595                        dst.provider = src.provider;
9596                        dst.proc = r;
9597                        dst.notifyAll();
9598                    }
9599                    updateOomAdjLocked(r);
9600                }
9601            }
9602
9603            Binder.restoreCallingIdentity(origId);
9604        }
9605    }
9606
9607    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9608        ContentProviderConnection conn;
9609        try {
9610            conn = (ContentProviderConnection)connection;
9611        } catch (ClassCastException e) {
9612            String msg ="refContentProvider: " + connection
9613                    + " not a ContentProviderConnection";
9614            Slog.w(TAG, msg);
9615            throw new IllegalArgumentException(msg);
9616        }
9617        if (conn == null) {
9618            throw new NullPointerException("connection is null");
9619        }
9620
9621        synchronized (this) {
9622            if (stable > 0) {
9623                conn.numStableIncs += stable;
9624            }
9625            stable = conn.stableCount + stable;
9626            if (stable < 0) {
9627                throw new IllegalStateException("stableCount < 0: " + stable);
9628            }
9629
9630            if (unstable > 0) {
9631                conn.numUnstableIncs += unstable;
9632            }
9633            unstable = conn.unstableCount + unstable;
9634            if (unstable < 0) {
9635                throw new IllegalStateException("unstableCount < 0: " + unstable);
9636            }
9637
9638            if ((stable+unstable) <= 0) {
9639                throw new IllegalStateException("ref counts can't go to zero here: stable="
9640                        + stable + " unstable=" + unstable);
9641            }
9642            conn.stableCount = stable;
9643            conn.unstableCount = unstable;
9644            return !conn.dead;
9645        }
9646    }
9647
9648    public void unstableProviderDied(IBinder connection) {
9649        ContentProviderConnection conn;
9650        try {
9651            conn = (ContentProviderConnection)connection;
9652        } catch (ClassCastException e) {
9653            String msg ="refContentProvider: " + connection
9654                    + " not a ContentProviderConnection";
9655            Slog.w(TAG, msg);
9656            throw new IllegalArgumentException(msg);
9657        }
9658        if (conn == null) {
9659            throw new NullPointerException("connection is null");
9660        }
9661
9662        // Safely retrieve the content provider associated with the connection.
9663        IContentProvider provider;
9664        synchronized (this) {
9665            provider = conn.provider.provider;
9666        }
9667
9668        if (provider == null) {
9669            // Um, yeah, we're way ahead of you.
9670            return;
9671        }
9672
9673        // Make sure the caller is being honest with us.
9674        if (provider.asBinder().pingBinder()) {
9675            // Er, no, still looks good to us.
9676            synchronized (this) {
9677                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9678                        + " says " + conn + " died, but we don't agree");
9679                return;
9680            }
9681        }
9682
9683        // Well look at that!  It's dead!
9684        synchronized (this) {
9685            if (conn.provider.provider != provider) {
9686                // But something changed...  good enough.
9687                return;
9688            }
9689
9690            ProcessRecord proc = conn.provider.proc;
9691            if (proc == null || proc.thread == null) {
9692                // Seems like the process is already cleaned up.
9693                return;
9694            }
9695
9696            // As far as we're concerned, this is just like receiving a
9697            // death notification...  just a bit prematurely.
9698            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9699                    + ") early provider death");
9700            final long ident = Binder.clearCallingIdentity();
9701            try {
9702                appDiedLocked(proc);
9703            } finally {
9704                Binder.restoreCallingIdentity(ident);
9705            }
9706        }
9707    }
9708
9709    @Override
9710    public void appNotRespondingViaProvider(IBinder connection) {
9711        enforceCallingPermission(
9712                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9713
9714        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9715        if (conn == null) {
9716            Slog.w(TAG, "ContentProviderConnection is null");
9717            return;
9718        }
9719
9720        final ProcessRecord host = conn.provider.proc;
9721        if (host == null) {
9722            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9723            return;
9724        }
9725
9726        final long token = Binder.clearCallingIdentity();
9727        try {
9728            appNotResponding(host, null, null, false, "ContentProvider not responding");
9729        } finally {
9730            Binder.restoreCallingIdentity(token);
9731        }
9732    }
9733
9734    public final void installSystemProviders() {
9735        List<ProviderInfo> providers;
9736        synchronized (this) {
9737            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9738            providers = generateApplicationProvidersLocked(app);
9739            if (providers != null) {
9740                for (int i=providers.size()-1; i>=0; i--) {
9741                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9742                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9743                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9744                                + ": not system .apk");
9745                        providers.remove(i);
9746                    }
9747                }
9748            }
9749        }
9750        if (providers != null) {
9751            mSystemThread.installSystemProviders(providers);
9752        }
9753
9754        mCoreSettingsObserver = new CoreSettingsObserver(this);
9755
9756        //mUsageStatsService.monitorPackages();
9757    }
9758
9759    /**
9760     * Allows apps to retrieve the MIME type of a URI.
9761     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9762     * users, then it does not need permission to access the ContentProvider.
9763     * Either, it needs cross-user uri grants.
9764     *
9765     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9766     *
9767     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9768     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9769     */
9770    public String getProviderMimeType(Uri uri, int userId) {
9771        enforceNotIsolatedCaller("getProviderMimeType");
9772        final String name = uri.getAuthority();
9773        int callingUid = Binder.getCallingUid();
9774        int callingPid = Binder.getCallingPid();
9775        long ident = 0;
9776        boolean clearedIdentity = false;
9777        userId = unsafeConvertIncomingUser(userId);
9778        if (canClearIdentity(callingPid, callingUid, userId)) {
9779            clearedIdentity = true;
9780            ident = Binder.clearCallingIdentity();
9781        }
9782        ContentProviderHolder holder = null;
9783        try {
9784            holder = getContentProviderExternalUnchecked(name, null, userId);
9785            if (holder != null) {
9786                return holder.provider.getType(uri);
9787            }
9788        } catch (RemoteException e) {
9789            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9790            return null;
9791        } finally {
9792            // We need to clear the identity to call removeContentProviderExternalUnchecked
9793            if (!clearedIdentity) {
9794                ident = Binder.clearCallingIdentity();
9795            }
9796            try {
9797                if (holder != null) {
9798                    removeContentProviderExternalUnchecked(name, null, userId);
9799                }
9800            } finally {
9801                Binder.restoreCallingIdentity(ident);
9802            }
9803        }
9804
9805        return null;
9806    }
9807
9808    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9809        if (UserHandle.getUserId(callingUid) == userId) {
9810            return true;
9811        }
9812        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9813                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9814                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9815                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9816                return true;
9817        }
9818        return false;
9819    }
9820
9821    // =========================================================
9822    // GLOBAL MANAGEMENT
9823    // =========================================================
9824
9825    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9826            boolean isolated, int isolatedUid) {
9827        String proc = customProcess != null ? customProcess : info.processName;
9828        BatteryStatsImpl.Uid.Proc ps = null;
9829        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9830        int uid = info.uid;
9831        if (isolated) {
9832            if (isolatedUid == 0) {
9833                int userId = UserHandle.getUserId(uid);
9834                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9835                while (true) {
9836                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9837                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9838                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9839                    }
9840                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9841                    mNextIsolatedProcessUid++;
9842                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9843                        // No process for this uid, use it.
9844                        break;
9845                    }
9846                    stepsLeft--;
9847                    if (stepsLeft <= 0) {
9848                        return null;
9849                    }
9850                }
9851            } else {
9852                // Special case for startIsolatedProcess (internal only), where
9853                // the uid of the isolated process is specified by the caller.
9854                uid = isolatedUid;
9855            }
9856        }
9857        return new ProcessRecord(stats, info, proc, uid);
9858    }
9859
9860    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9861            String abiOverride) {
9862        ProcessRecord app;
9863        if (!isolated) {
9864            app = getProcessRecordLocked(info.processName, info.uid, true);
9865        } else {
9866            app = null;
9867        }
9868
9869        if (app == null) {
9870            app = newProcessRecordLocked(info, null, isolated, 0);
9871            mProcessNames.put(info.processName, app.uid, app);
9872            if (isolated) {
9873                mIsolatedProcesses.put(app.uid, app);
9874            }
9875            updateLruProcessLocked(app, false, null);
9876            updateOomAdjLocked();
9877        }
9878
9879        // This package really, really can not be stopped.
9880        try {
9881            AppGlobals.getPackageManager().setPackageStoppedState(
9882                    info.packageName, false, UserHandle.getUserId(app.uid));
9883        } catch (RemoteException e) {
9884        } catch (IllegalArgumentException e) {
9885            Slog.w(TAG, "Failed trying to unstop package "
9886                    + info.packageName + ": " + e);
9887        }
9888
9889        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9890                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9891            app.persistent = true;
9892            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9893        }
9894        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9895            mPersistentStartingProcesses.add(app);
9896            startProcessLocked(app, "added application", app.processName, abiOverride,
9897                    null /* entryPoint */, null /* entryPointArgs */);
9898        }
9899
9900        return app;
9901    }
9902
9903    public void unhandledBack() {
9904        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9905                "unhandledBack()");
9906
9907        synchronized(this) {
9908            final long origId = Binder.clearCallingIdentity();
9909            try {
9910                getFocusedStack().unhandledBackLocked();
9911            } finally {
9912                Binder.restoreCallingIdentity(origId);
9913            }
9914        }
9915    }
9916
9917    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9918        enforceNotIsolatedCaller("openContentUri");
9919        final int userId = UserHandle.getCallingUserId();
9920        String name = uri.getAuthority();
9921        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9922        ParcelFileDescriptor pfd = null;
9923        if (cph != null) {
9924            // We record the binder invoker's uid in thread-local storage before
9925            // going to the content provider to open the file.  Later, in the code
9926            // that handles all permissions checks, we look for this uid and use
9927            // that rather than the Activity Manager's own uid.  The effect is that
9928            // we do the check against the caller's permissions even though it looks
9929            // to the content provider like the Activity Manager itself is making
9930            // the request.
9931            Binder token = new Binder();
9932            sCallerIdentity.set(new Identity(
9933                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9934            try {
9935                pfd = cph.provider.openFile(null, uri, "r", null, token);
9936            } catch (FileNotFoundException e) {
9937                // do nothing; pfd will be returned null
9938            } finally {
9939                // Ensure that whatever happens, we clean up the identity state
9940                sCallerIdentity.remove();
9941            }
9942
9943            // We've got the fd now, so we're done with the provider.
9944            removeContentProviderExternalUnchecked(name, null, userId);
9945        } else {
9946            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9947        }
9948        return pfd;
9949    }
9950
9951    // Actually is sleeping or shutting down or whatever else in the future
9952    // is an inactive state.
9953    public boolean isSleepingOrShuttingDown() {
9954        return isSleeping() || mShuttingDown;
9955    }
9956
9957    public boolean isSleeping() {
9958        return mSleeping;
9959    }
9960
9961    void onWakefulnessChanged(int wakefulness) {
9962        synchronized(this) {
9963            mWakefulness = wakefulness;
9964            updateSleepIfNeededLocked();
9965        }
9966    }
9967
9968    void finishRunningVoiceLocked() {
9969        if (mRunningVoice) {
9970            mRunningVoice = false;
9971            updateSleepIfNeededLocked();
9972        }
9973    }
9974
9975    void updateSleepIfNeededLocked() {
9976        if (mSleeping && !shouldSleepLocked()) {
9977            mSleeping = false;
9978            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9979        } else if (!mSleeping && shouldSleepLocked()) {
9980            mSleeping = true;
9981            mStackSupervisor.goingToSleepLocked();
9982
9983            // Initialize the wake times of all processes.
9984            checkExcessivePowerUsageLocked(false);
9985            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9986            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9987            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9988        }
9989    }
9990
9991    private boolean shouldSleepLocked() {
9992        // Resume applications while running a voice interactor.
9993        if (mRunningVoice) {
9994            return false;
9995        }
9996
9997        switch (mWakefulness) {
9998            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9999            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10000                // If we're interactive but applications are already paused then defer
10001                // resuming them until the lock screen is hidden.
10002                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10003            case PowerManagerInternal.WAKEFULNESS_DOZING:
10004                // If we're dozing then pause applications whenever the lock screen is shown.
10005                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10006            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10007            default:
10008                // If we're asleep then pause applications unconditionally.
10009                return true;
10010        }
10011    }
10012
10013    /** Pokes the task persister. */
10014    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10015        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10016            // Never persist the home stack.
10017            return;
10018        }
10019        mTaskPersister.wakeup(task, flush);
10020    }
10021
10022    /** Notifies all listeners when the task stack has changed. */
10023    void notifyTaskStackChangedLocked() {
10024        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10025        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10026        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10027    }
10028
10029    @Override
10030    public boolean shutdown(int timeout) {
10031        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10032                != PackageManager.PERMISSION_GRANTED) {
10033            throw new SecurityException("Requires permission "
10034                    + android.Manifest.permission.SHUTDOWN);
10035        }
10036
10037        boolean timedout = false;
10038
10039        synchronized(this) {
10040            mShuttingDown = true;
10041            updateEventDispatchingLocked();
10042            timedout = mStackSupervisor.shutdownLocked(timeout);
10043        }
10044
10045        mAppOpsService.shutdown();
10046        if (mUsageStatsService != null) {
10047            mUsageStatsService.prepareShutdown();
10048        }
10049        mBatteryStatsService.shutdown();
10050        synchronized (this) {
10051            mProcessStats.shutdownLocked();
10052            notifyTaskPersisterLocked(null, true);
10053        }
10054
10055        return timedout;
10056    }
10057
10058    public final void activitySlept(IBinder token) {
10059        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10060
10061        final long origId = Binder.clearCallingIdentity();
10062
10063        synchronized (this) {
10064            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10065            if (r != null) {
10066                mStackSupervisor.activitySleptLocked(r);
10067            }
10068        }
10069
10070        Binder.restoreCallingIdentity(origId);
10071    }
10072
10073    private String lockScreenShownToString() {
10074        switch (mLockScreenShown) {
10075            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10076            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10077            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10078            default: return "Unknown=" + mLockScreenShown;
10079        }
10080    }
10081
10082    void logLockScreen(String msg) {
10083        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10084                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10085                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10086                + " mSleeping=" + mSleeping);
10087    }
10088
10089    void startRunningVoiceLocked() {
10090        if (!mRunningVoice) {
10091            mRunningVoice = true;
10092            updateSleepIfNeededLocked();
10093        }
10094    }
10095
10096    private void updateEventDispatchingLocked() {
10097        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10098    }
10099
10100    public void setLockScreenShown(boolean shown) {
10101        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10102                != PackageManager.PERMISSION_GRANTED) {
10103            throw new SecurityException("Requires permission "
10104                    + android.Manifest.permission.DEVICE_POWER);
10105        }
10106
10107        synchronized(this) {
10108            long ident = Binder.clearCallingIdentity();
10109            try {
10110                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10111                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10112                updateSleepIfNeededLocked();
10113            } finally {
10114                Binder.restoreCallingIdentity(ident);
10115            }
10116        }
10117    }
10118
10119    @Override
10120    public void stopAppSwitches() {
10121        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10122                != PackageManager.PERMISSION_GRANTED) {
10123            throw new SecurityException("Requires permission "
10124                    + android.Manifest.permission.STOP_APP_SWITCHES);
10125        }
10126
10127        synchronized(this) {
10128            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10129                    + APP_SWITCH_DELAY_TIME;
10130            mDidAppSwitch = false;
10131            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10132            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10133            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10134        }
10135    }
10136
10137    public void resumeAppSwitches() {
10138        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10139                != PackageManager.PERMISSION_GRANTED) {
10140            throw new SecurityException("Requires permission "
10141                    + android.Manifest.permission.STOP_APP_SWITCHES);
10142        }
10143
10144        synchronized(this) {
10145            // Note that we don't execute any pending app switches... we will
10146            // let those wait until either the timeout, or the next start
10147            // activity request.
10148            mAppSwitchesAllowedTime = 0;
10149        }
10150    }
10151
10152    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10153            int callingPid, int callingUid, String name) {
10154        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10155            return true;
10156        }
10157
10158        int perm = checkComponentPermission(
10159                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10160                sourceUid, -1, true);
10161        if (perm == PackageManager.PERMISSION_GRANTED) {
10162            return true;
10163        }
10164
10165        // If the actual IPC caller is different from the logical source, then
10166        // also see if they are allowed to control app switches.
10167        if (callingUid != -1 && callingUid != sourceUid) {
10168            perm = checkComponentPermission(
10169                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10170                    callingUid, -1, true);
10171            if (perm == PackageManager.PERMISSION_GRANTED) {
10172                return true;
10173            }
10174        }
10175
10176        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10177        return false;
10178    }
10179
10180    public void setDebugApp(String packageName, boolean waitForDebugger,
10181            boolean persistent) {
10182        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10183                "setDebugApp()");
10184
10185        long ident = Binder.clearCallingIdentity();
10186        try {
10187            // Note that this is not really thread safe if there are multiple
10188            // callers into it at the same time, but that's not a situation we
10189            // care about.
10190            if (persistent) {
10191                final ContentResolver resolver = mContext.getContentResolver();
10192                Settings.Global.putString(
10193                    resolver, Settings.Global.DEBUG_APP,
10194                    packageName);
10195                Settings.Global.putInt(
10196                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10197                    waitForDebugger ? 1 : 0);
10198            }
10199
10200            synchronized (this) {
10201                if (!persistent) {
10202                    mOrigDebugApp = mDebugApp;
10203                    mOrigWaitForDebugger = mWaitForDebugger;
10204                }
10205                mDebugApp = packageName;
10206                mWaitForDebugger = waitForDebugger;
10207                mDebugTransient = !persistent;
10208                if (packageName != null) {
10209                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10210                            false, UserHandle.USER_ALL, "set debug app");
10211                }
10212            }
10213        } finally {
10214            Binder.restoreCallingIdentity(ident);
10215        }
10216    }
10217
10218    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10219        synchronized (this) {
10220            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10221            if (!isDebuggable) {
10222                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10223                    throw new SecurityException("Process not debuggable: " + app.packageName);
10224                }
10225            }
10226
10227            mOpenGlTraceApp = processName;
10228        }
10229    }
10230
10231    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10232        synchronized (this) {
10233            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10234            if (!isDebuggable) {
10235                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10236                    throw new SecurityException("Process not debuggable: " + app.packageName);
10237                }
10238            }
10239            mProfileApp = processName;
10240            mProfileFile = profilerInfo.profileFile;
10241            if (mProfileFd != null) {
10242                try {
10243                    mProfileFd.close();
10244                } catch (IOException e) {
10245                }
10246                mProfileFd = null;
10247            }
10248            mProfileFd = profilerInfo.profileFd;
10249            mSamplingInterval = profilerInfo.samplingInterval;
10250            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10251            mProfileType = 0;
10252        }
10253    }
10254
10255    @Override
10256    public void setAlwaysFinish(boolean enabled) {
10257        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10258                "setAlwaysFinish()");
10259
10260        Settings.Global.putInt(
10261                mContext.getContentResolver(),
10262                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10263
10264        synchronized (this) {
10265            mAlwaysFinishActivities = enabled;
10266        }
10267    }
10268
10269    @Override
10270    public void setActivityController(IActivityController controller) {
10271        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10272                "setActivityController()");
10273        synchronized (this) {
10274            mController = controller;
10275            Watchdog.getInstance().setActivityController(controller);
10276        }
10277    }
10278
10279    @Override
10280    public void setUserIsMonkey(boolean userIsMonkey) {
10281        synchronized (this) {
10282            synchronized (mPidsSelfLocked) {
10283                final int callingPid = Binder.getCallingPid();
10284                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10285                if (precessRecord == null) {
10286                    throw new SecurityException("Unknown process: " + callingPid);
10287                }
10288                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10289                    throw new SecurityException("Only an instrumentation process "
10290                            + "with a UiAutomation can call setUserIsMonkey");
10291                }
10292            }
10293            mUserIsMonkey = userIsMonkey;
10294        }
10295    }
10296
10297    @Override
10298    public boolean isUserAMonkey() {
10299        synchronized (this) {
10300            // If there is a controller also implies the user is a monkey.
10301            return (mUserIsMonkey || mController != null);
10302        }
10303    }
10304
10305    public void requestBugReport() {
10306        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10307        SystemProperties.set("ctl.start", "bugreport");
10308    }
10309
10310    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10311        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10312    }
10313
10314    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10315        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10316            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10317        }
10318        return KEY_DISPATCHING_TIMEOUT;
10319    }
10320
10321    @Override
10322    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10323        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10324                != PackageManager.PERMISSION_GRANTED) {
10325            throw new SecurityException("Requires permission "
10326                    + android.Manifest.permission.FILTER_EVENTS);
10327        }
10328        ProcessRecord proc;
10329        long timeout;
10330        synchronized (this) {
10331            synchronized (mPidsSelfLocked) {
10332                proc = mPidsSelfLocked.get(pid);
10333            }
10334            timeout = getInputDispatchingTimeoutLocked(proc);
10335        }
10336
10337        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10338            return -1;
10339        }
10340
10341        return timeout;
10342    }
10343
10344    /**
10345     * Handle input dispatching timeouts.
10346     * Returns whether input dispatching should be aborted or not.
10347     */
10348    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10349            final ActivityRecord activity, final ActivityRecord parent,
10350            final boolean aboveSystem, String reason) {
10351        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10352                != PackageManager.PERMISSION_GRANTED) {
10353            throw new SecurityException("Requires permission "
10354                    + android.Manifest.permission.FILTER_EVENTS);
10355        }
10356
10357        final String annotation;
10358        if (reason == null) {
10359            annotation = "Input dispatching timed out";
10360        } else {
10361            annotation = "Input dispatching timed out (" + reason + ")";
10362        }
10363
10364        if (proc != null) {
10365            synchronized (this) {
10366                if (proc.debugging) {
10367                    return false;
10368                }
10369
10370                if (mDidDexOpt) {
10371                    // Give more time since we were dexopting.
10372                    mDidDexOpt = false;
10373                    return false;
10374                }
10375
10376                if (proc.instrumentationClass != null) {
10377                    Bundle info = new Bundle();
10378                    info.putString("shortMsg", "keyDispatchingTimedOut");
10379                    info.putString("longMsg", annotation);
10380                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10381                    return true;
10382                }
10383            }
10384            mHandler.post(new Runnable() {
10385                @Override
10386                public void run() {
10387                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10388                }
10389            });
10390        }
10391
10392        return true;
10393    }
10394
10395    public Bundle getAssistContextExtras(int requestType) {
10396        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10397                UserHandle.getCallingUserId());
10398        if (pae == null) {
10399            return null;
10400        }
10401        synchronized (pae) {
10402            while (!pae.haveResult) {
10403                try {
10404                    pae.wait();
10405                } catch (InterruptedException e) {
10406                }
10407            }
10408            if (pae.result != null) {
10409                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10410            }
10411        }
10412        synchronized (this) {
10413            mPendingAssistExtras.remove(pae);
10414            mHandler.removeCallbacks(pae);
10415        }
10416        return pae.extras;
10417    }
10418
10419    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10420            int userHandle) {
10421        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10422                "getAssistContextExtras()");
10423        PendingAssistExtras pae;
10424        Bundle extras = new Bundle();
10425        synchronized (this) {
10426            ActivityRecord activity = getFocusedStack().mResumedActivity;
10427            if (activity == null) {
10428                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10429                return null;
10430            }
10431            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10432            if (activity.app == null || activity.app.thread == null) {
10433                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10434                return null;
10435            }
10436            if (activity.app.pid == Binder.getCallingPid()) {
10437                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10438                return null;
10439            }
10440            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10441            try {
10442                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10443                        requestType);
10444                mPendingAssistExtras.add(pae);
10445                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10446            } catch (RemoteException e) {
10447                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10448                return null;
10449            }
10450            return pae;
10451        }
10452    }
10453
10454    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10455        PendingAssistExtras pae = (PendingAssistExtras)token;
10456        synchronized (pae) {
10457            pae.result = extras;
10458            pae.haveResult = true;
10459            pae.notifyAll();
10460            if (pae.intent == null) {
10461                // Caller is just waiting for the result.
10462                return;
10463            }
10464        }
10465
10466        // We are now ready to launch the assist activity.
10467        synchronized (this) {
10468            boolean exists = mPendingAssistExtras.remove(pae);
10469            mHandler.removeCallbacks(pae);
10470            if (!exists) {
10471                // Timed out.
10472                return;
10473            }
10474        }
10475        pae.intent.replaceExtras(extras);
10476        if (pae.hint != null) {
10477            pae.intent.putExtra(pae.hint, true);
10478        }
10479        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10480                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10481                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10482        closeSystemDialogs("assist");
10483        try {
10484            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10485        } catch (ActivityNotFoundException e) {
10486            Slog.w(TAG, "No activity to handle assist action.", e);
10487        }
10488    }
10489
10490    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10491        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10492    }
10493
10494    public void registerProcessObserver(IProcessObserver observer) {
10495        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10496                "registerProcessObserver()");
10497        synchronized (this) {
10498            mProcessObservers.register(observer);
10499        }
10500    }
10501
10502    @Override
10503    public void unregisterProcessObserver(IProcessObserver observer) {
10504        synchronized (this) {
10505            mProcessObservers.unregister(observer);
10506        }
10507    }
10508
10509    @Override
10510    public boolean convertFromTranslucent(IBinder token) {
10511        final long origId = Binder.clearCallingIdentity();
10512        try {
10513            synchronized (this) {
10514                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10515                if (r == null) {
10516                    return false;
10517                }
10518                final boolean translucentChanged = r.changeWindowTranslucency(true);
10519                if (translucentChanged) {
10520                    r.task.stack.releaseBackgroundResources();
10521                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10522                }
10523                mWindowManager.setAppFullscreen(token, true);
10524                return translucentChanged;
10525            }
10526        } finally {
10527            Binder.restoreCallingIdentity(origId);
10528        }
10529    }
10530
10531    @Override
10532    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10533        final long origId = Binder.clearCallingIdentity();
10534        try {
10535            synchronized (this) {
10536                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10537                if (r == null) {
10538                    return false;
10539                }
10540                int index = r.task.mActivities.lastIndexOf(r);
10541                if (index > 0) {
10542                    ActivityRecord under = r.task.mActivities.get(index - 1);
10543                    under.returningOptions = options;
10544                }
10545                final boolean translucentChanged = r.changeWindowTranslucency(false);
10546                if (translucentChanged) {
10547                    r.task.stack.convertToTranslucent(r);
10548                }
10549                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10550                mWindowManager.setAppFullscreen(token, false);
10551                return translucentChanged;
10552            }
10553        } finally {
10554            Binder.restoreCallingIdentity(origId);
10555        }
10556    }
10557
10558    @Override
10559    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10560        final long origId = Binder.clearCallingIdentity();
10561        try {
10562            synchronized (this) {
10563                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10564                if (r != null) {
10565                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10566                }
10567            }
10568            return false;
10569        } finally {
10570            Binder.restoreCallingIdentity(origId);
10571        }
10572    }
10573
10574    @Override
10575    public boolean isBackgroundVisibleBehind(IBinder token) {
10576        final long origId = Binder.clearCallingIdentity();
10577        try {
10578            synchronized (this) {
10579                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10580                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10581                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10582                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10583                return visible;
10584            }
10585        } finally {
10586            Binder.restoreCallingIdentity(origId);
10587        }
10588    }
10589
10590    @Override
10591    public ActivityOptions getActivityOptions(IBinder token) {
10592        final long origId = Binder.clearCallingIdentity();
10593        try {
10594            synchronized (this) {
10595                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10596                if (r != null) {
10597                    final ActivityOptions activityOptions = r.pendingOptions;
10598                    r.pendingOptions = null;
10599                    return activityOptions;
10600                }
10601                return null;
10602            }
10603        } finally {
10604            Binder.restoreCallingIdentity(origId);
10605        }
10606    }
10607
10608    @Override
10609    public void setImmersive(IBinder token, boolean immersive) {
10610        synchronized(this) {
10611            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10612            if (r == null) {
10613                throw new IllegalArgumentException();
10614            }
10615            r.immersive = immersive;
10616
10617            // update associated state if we're frontmost
10618            if (r == mFocusedActivity) {
10619                if (DEBUG_IMMERSIVE) {
10620                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10621                }
10622                applyUpdateLockStateLocked(r);
10623            }
10624        }
10625    }
10626
10627    @Override
10628    public boolean isImmersive(IBinder token) {
10629        synchronized (this) {
10630            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10631            if (r == null) {
10632                throw new IllegalArgumentException();
10633            }
10634            return r.immersive;
10635        }
10636    }
10637
10638    public boolean isTopActivityImmersive() {
10639        enforceNotIsolatedCaller("startActivity");
10640        synchronized (this) {
10641            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10642            return (r != null) ? r.immersive : false;
10643        }
10644    }
10645
10646    @Override
10647    public boolean isTopOfTask(IBinder token) {
10648        synchronized (this) {
10649            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10650            if (r == null) {
10651                throw new IllegalArgumentException();
10652            }
10653            return r.task.getTopActivity() == r;
10654        }
10655    }
10656
10657    public final void enterSafeMode() {
10658        synchronized(this) {
10659            // It only makes sense to do this before the system is ready
10660            // and started launching other packages.
10661            if (!mSystemReady) {
10662                try {
10663                    AppGlobals.getPackageManager().enterSafeMode();
10664                } catch (RemoteException e) {
10665                }
10666            }
10667
10668            mSafeMode = true;
10669        }
10670    }
10671
10672    public final void showSafeModeOverlay() {
10673        View v = LayoutInflater.from(mContext).inflate(
10674                com.android.internal.R.layout.safe_mode, null);
10675        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10676        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10677        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10678        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10679        lp.gravity = Gravity.BOTTOM | Gravity.START;
10680        lp.format = v.getBackground().getOpacity();
10681        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10682                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10683        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10684        ((WindowManager)mContext.getSystemService(
10685                Context.WINDOW_SERVICE)).addView(v, lp);
10686    }
10687
10688    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10689        if (!(sender instanceof PendingIntentRecord)) {
10690            return;
10691        }
10692        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10693        synchronized (stats) {
10694            if (mBatteryStatsService.isOnBattery()) {
10695                mBatteryStatsService.enforceCallingPermission();
10696                PendingIntentRecord rec = (PendingIntentRecord)sender;
10697                int MY_UID = Binder.getCallingUid();
10698                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10699                BatteryStatsImpl.Uid.Pkg pkg =
10700                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10701                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10702                pkg.incWakeupsLocked();
10703            }
10704        }
10705    }
10706
10707    public boolean killPids(int[] pids, String pReason, boolean secure) {
10708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10709            throw new SecurityException("killPids only available to the system");
10710        }
10711        String reason = (pReason == null) ? "Unknown" : pReason;
10712        // XXX Note: don't acquire main activity lock here, because the window
10713        // manager calls in with its locks held.
10714
10715        boolean killed = false;
10716        synchronized (mPidsSelfLocked) {
10717            int[] types = new int[pids.length];
10718            int worstType = 0;
10719            for (int i=0; i<pids.length; i++) {
10720                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10721                if (proc != null) {
10722                    int type = proc.setAdj;
10723                    types[i] = type;
10724                    if (type > worstType) {
10725                        worstType = type;
10726                    }
10727                }
10728            }
10729
10730            // If the worst oom_adj is somewhere in the cached proc LRU range,
10731            // then constrain it so we will kill all cached procs.
10732            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10733                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10734                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10735            }
10736
10737            // If this is not a secure call, don't let it kill processes that
10738            // are important.
10739            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10740                worstType = ProcessList.SERVICE_ADJ;
10741            }
10742
10743            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10744            for (int i=0; i<pids.length; i++) {
10745                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10746                if (proc == null) {
10747                    continue;
10748                }
10749                int adj = proc.setAdj;
10750                if (adj >= worstType && !proc.killedByAm) {
10751                    proc.kill(reason, true);
10752                    killed = true;
10753                }
10754            }
10755        }
10756        return killed;
10757    }
10758
10759    @Override
10760    public void killUid(int uid, String reason) {
10761        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10762            throw new SecurityException("killUid only available to the system");
10763        }
10764        synchronized (this) {
10765            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10766                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10767                    reason != null ? reason : "kill uid");
10768        }
10769    }
10770
10771    @Override
10772    public boolean killProcessesBelowForeground(String reason) {
10773        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10774            throw new SecurityException("killProcessesBelowForeground() only available to system");
10775        }
10776
10777        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10778    }
10779
10780    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10781        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10782            throw new SecurityException("killProcessesBelowAdj() only available to system");
10783        }
10784
10785        boolean killed = false;
10786        synchronized (mPidsSelfLocked) {
10787            final int size = mPidsSelfLocked.size();
10788            for (int i = 0; i < size; i++) {
10789                final int pid = mPidsSelfLocked.keyAt(i);
10790                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10791                if (proc == null) continue;
10792
10793                final int adj = proc.setAdj;
10794                if (adj > belowAdj && !proc.killedByAm) {
10795                    proc.kill(reason, true);
10796                    killed = true;
10797                }
10798            }
10799        }
10800        return killed;
10801    }
10802
10803    @Override
10804    public void hang(final IBinder who, boolean allowRestart) {
10805        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10806                != PackageManager.PERMISSION_GRANTED) {
10807            throw new SecurityException("Requires permission "
10808                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10809        }
10810
10811        final IBinder.DeathRecipient death = new DeathRecipient() {
10812            @Override
10813            public void binderDied() {
10814                synchronized (this) {
10815                    notifyAll();
10816                }
10817            }
10818        };
10819
10820        try {
10821            who.linkToDeath(death, 0);
10822        } catch (RemoteException e) {
10823            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10824            return;
10825        }
10826
10827        synchronized (this) {
10828            Watchdog.getInstance().setAllowRestart(allowRestart);
10829            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10830            synchronized (death) {
10831                while (who.isBinderAlive()) {
10832                    try {
10833                        death.wait();
10834                    } catch (InterruptedException e) {
10835                    }
10836                }
10837            }
10838            Watchdog.getInstance().setAllowRestart(true);
10839        }
10840    }
10841
10842    @Override
10843    public void restart() {
10844        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10845                != PackageManager.PERMISSION_GRANTED) {
10846            throw new SecurityException("Requires permission "
10847                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10848        }
10849
10850        Log.i(TAG, "Sending shutdown broadcast...");
10851
10852        BroadcastReceiver br = new BroadcastReceiver() {
10853            @Override public void onReceive(Context context, Intent intent) {
10854                // Now the broadcast is done, finish up the low-level shutdown.
10855                Log.i(TAG, "Shutting down activity manager...");
10856                shutdown(10000);
10857                Log.i(TAG, "Shutdown complete, restarting!");
10858                Process.killProcess(Process.myPid());
10859                System.exit(10);
10860            }
10861        };
10862
10863        // First send the high-level shut down broadcast.
10864        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10865        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10866        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10867        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10868        mContext.sendOrderedBroadcastAsUser(intent,
10869                UserHandle.ALL, null, br, mHandler, 0, null, null);
10870        */
10871        br.onReceive(mContext, intent);
10872    }
10873
10874    private long getLowRamTimeSinceIdle(long now) {
10875        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10876    }
10877
10878    @Override
10879    public void performIdleMaintenance() {
10880        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10881                != PackageManager.PERMISSION_GRANTED) {
10882            throw new SecurityException("Requires permission "
10883                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10884        }
10885
10886        synchronized (this) {
10887            final long now = SystemClock.uptimeMillis();
10888            final long timeSinceLastIdle = now - mLastIdleTime;
10889            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10890            mLastIdleTime = now;
10891            mLowRamTimeSinceLastIdle = 0;
10892            if (mLowRamStartTime != 0) {
10893                mLowRamStartTime = now;
10894            }
10895
10896            StringBuilder sb = new StringBuilder(128);
10897            sb.append("Idle maintenance over ");
10898            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10899            sb.append(" low RAM for ");
10900            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10901            Slog.i(TAG, sb.toString());
10902
10903            // If at least 1/3 of our time since the last idle period has been spent
10904            // with RAM low, then we want to kill processes.
10905            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10906
10907            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10908                ProcessRecord proc = mLruProcesses.get(i);
10909                if (proc.notCachedSinceIdle) {
10910                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10911                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10912                        if (doKilling && proc.initialIdlePss != 0
10913                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10914                            proc.kill("idle maint (pss " + proc.lastPss
10915                                    + " from " + proc.initialIdlePss + ")", true);
10916                        }
10917                    }
10918                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10919                    proc.notCachedSinceIdle = true;
10920                    proc.initialIdlePss = 0;
10921                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10922                            isSleeping(), now);
10923                }
10924            }
10925
10926            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10927            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10928        }
10929    }
10930
10931    private void retrieveSettings() {
10932        final ContentResolver resolver = mContext.getContentResolver();
10933        String debugApp = Settings.Global.getString(
10934            resolver, Settings.Global.DEBUG_APP);
10935        boolean waitForDebugger = Settings.Global.getInt(
10936            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10937        boolean alwaysFinishActivities = Settings.Global.getInt(
10938            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10939        boolean forceRtl = Settings.Global.getInt(
10940                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10941        // Transfer any global setting for forcing RTL layout, into a System Property
10942        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10943
10944        Configuration configuration = new Configuration();
10945        Settings.System.getConfiguration(resolver, configuration);
10946        if (forceRtl) {
10947            // This will take care of setting the correct layout direction flags
10948            configuration.setLayoutDirection(configuration.locale);
10949        }
10950
10951        synchronized (this) {
10952            mDebugApp = mOrigDebugApp = debugApp;
10953            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10954            mAlwaysFinishActivities = alwaysFinishActivities;
10955            // This happens before any activities are started, so we can
10956            // change mConfiguration in-place.
10957            updateConfigurationLocked(configuration, null, false, true);
10958            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10959        }
10960    }
10961
10962    /** Loads resources after the current configuration has been set. */
10963    private void loadResourcesOnSystemReady() {
10964        final Resources res = mContext.getResources();
10965        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10966        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10967        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10968    }
10969
10970    public boolean testIsSystemReady() {
10971        // no need to synchronize(this) just to read & return the value
10972        return mSystemReady;
10973    }
10974
10975    private static File getCalledPreBootReceiversFile() {
10976        File dataDir = Environment.getDataDirectory();
10977        File systemDir = new File(dataDir, "system");
10978        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10979        return fname;
10980    }
10981
10982    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10983        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10984        File file = getCalledPreBootReceiversFile();
10985        FileInputStream fis = null;
10986        try {
10987            fis = new FileInputStream(file);
10988            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10989            int fvers = dis.readInt();
10990            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10991                String vers = dis.readUTF();
10992                String codename = dis.readUTF();
10993                String build = dis.readUTF();
10994                if (android.os.Build.VERSION.RELEASE.equals(vers)
10995                        && android.os.Build.VERSION.CODENAME.equals(codename)
10996                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10997                    int num = dis.readInt();
10998                    while (num > 0) {
10999                        num--;
11000                        String pkg = dis.readUTF();
11001                        String cls = dis.readUTF();
11002                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11003                    }
11004                }
11005            }
11006        } catch (FileNotFoundException e) {
11007        } catch (IOException e) {
11008            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11009        } finally {
11010            if (fis != null) {
11011                try {
11012                    fis.close();
11013                } catch (IOException e) {
11014                }
11015            }
11016        }
11017        return lastDoneReceivers;
11018    }
11019
11020    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11021        File file = getCalledPreBootReceiversFile();
11022        FileOutputStream fos = null;
11023        DataOutputStream dos = null;
11024        try {
11025            fos = new FileOutputStream(file);
11026            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11027            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11028            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11029            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11030            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11031            dos.writeInt(list.size());
11032            for (int i=0; i<list.size(); i++) {
11033                dos.writeUTF(list.get(i).getPackageName());
11034                dos.writeUTF(list.get(i).getClassName());
11035            }
11036        } catch (IOException e) {
11037            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11038            file.delete();
11039        } finally {
11040            FileUtils.sync(fos);
11041            if (dos != null) {
11042                try {
11043                    dos.close();
11044                } catch (IOException e) {
11045                    // TODO Auto-generated catch block
11046                    e.printStackTrace();
11047                }
11048            }
11049        }
11050    }
11051
11052    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11053            ArrayList<ComponentName> doneReceivers, int userId) {
11054        boolean waitingUpdate = false;
11055        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11056        List<ResolveInfo> ris = null;
11057        try {
11058            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11059                    intent, null, 0, userId);
11060        } catch (RemoteException e) {
11061        }
11062        if (ris != null) {
11063            for (int i=ris.size()-1; i>=0; i--) {
11064                if ((ris.get(i).activityInfo.applicationInfo.flags
11065                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11066                    ris.remove(i);
11067                }
11068            }
11069            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11070
11071            // For User 0, load the version number. When delivering to a new user, deliver
11072            // to all receivers.
11073            if (userId == UserHandle.USER_OWNER) {
11074                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11075                for (int i=0; i<ris.size(); i++) {
11076                    ActivityInfo ai = ris.get(i).activityInfo;
11077                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11078                    if (lastDoneReceivers.contains(comp)) {
11079                        // We already did the pre boot receiver for this app with the current
11080                        // platform version, so don't do it again...
11081                        ris.remove(i);
11082                        i--;
11083                        // ...however, do keep it as one that has been done, so we don't
11084                        // forget about it when rewriting the file of last done receivers.
11085                        doneReceivers.add(comp);
11086                    }
11087                }
11088            }
11089
11090            // If primary user, send broadcast to all available users, else just to userId
11091            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11092                    : new int[] { userId };
11093            for (int i = 0; i < ris.size(); i++) {
11094                ActivityInfo ai = ris.get(i).activityInfo;
11095                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11096                doneReceivers.add(comp);
11097                intent.setComponent(comp);
11098                for (int j=0; j<users.length; j++) {
11099                    IIntentReceiver finisher = null;
11100                    // On last receiver and user, set up a completion callback
11101                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11102                        finisher = new IIntentReceiver.Stub() {
11103                            public void performReceive(Intent intent, int resultCode,
11104                                    String data, Bundle extras, boolean ordered,
11105                                    boolean sticky, int sendingUser) {
11106                                // The raw IIntentReceiver interface is called
11107                                // with the AM lock held, so redispatch to
11108                                // execute our code without the lock.
11109                                mHandler.post(onFinishCallback);
11110                            }
11111                        };
11112                    }
11113                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11114                            + " for user " + users[j]);
11115                    broadcastIntentLocked(null, null, intent, null, finisher,
11116                            0, null, null, null, AppOpsManager.OP_NONE,
11117                            true, false, MY_PID, Process.SYSTEM_UID,
11118                            users[j]);
11119                    if (finisher != null) {
11120                        waitingUpdate = true;
11121                    }
11122                }
11123            }
11124        }
11125
11126        return waitingUpdate;
11127    }
11128
11129    public void systemReady(final Runnable goingCallback) {
11130        synchronized(this) {
11131            if (mSystemReady) {
11132                // If we're done calling all the receivers, run the next "boot phase" passed in
11133                // by the SystemServer
11134                if (goingCallback != null) {
11135                    goingCallback.run();
11136                }
11137                return;
11138            }
11139
11140            // Make sure we have the current profile info, since it is needed for
11141            // security checks.
11142            updateCurrentProfileIdsLocked();
11143
11144            if (mRecentTasks == null) {
11145                mRecentTasks = mTaskPersister.restoreTasksLocked();
11146                if (!mRecentTasks.isEmpty()) {
11147                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11148                }
11149                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11150                mTaskPersister.startPersisting();
11151            }
11152
11153            // Check to see if there are any update receivers to run.
11154            if (!mDidUpdate) {
11155                if (mWaitingUpdate) {
11156                    return;
11157                }
11158                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11159                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11160                    public void run() {
11161                        synchronized (ActivityManagerService.this) {
11162                            mDidUpdate = true;
11163                        }
11164                        writeLastDonePreBootReceivers(doneReceivers);
11165                        showBootMessage(mContext.getText(
11166                                R.string.android_upgrading_complete),
11167                                false);
11168                        systemReady(goingCallback);
11169                    }
11170                }, doneReceivers, UserHandle.USER_OWNER);
11171
11172                if (mWaitingUpdate) {
11173                    return;
11174                }
11175                mDidUpdate = true;
11176            }
11177
11178            mAppOpsService.systemReady();
11179            mSystemReady = true;
11180        }
11181
11182        ArrayList<ProcessRecord> procsToKill = null;
11183        synchronized(mPidsSelfLocked) {
11184            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11185                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11186                if (!isAllowedWhileBooting(proc.info)){
11187                    if (procsToKill == null) {
11188                        procsToKill = new ArrayList<ProcessRecord>();
11189                    }
11190                    procsToKill.add(proc);
11191                }
11192            }
11193        }
11194
11195        synchronized(this) {
11196            if (procsToKill != null) {
11197                for (int i=procsToKill.size()-1; i>=0; i--) {
11198                    ProcessRecord proc = procsToKill.get(i);
11199                    Slog.i(TAG, "Removing system update proc: " + proc);
11200                    removeProcessLocked(proc, true, false, "system update done");
11201                }
11202            }
11203
11204            // Now that we have cleaned up any update processes, we
11205            // are ready to start launching real processes and know that
11206            // we won't trample on them any more.
11207            mProcessesReady = true;
11208        }
11209
11210        Slog.i(TAG, "System now ready");
11211        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11212            SystemClock.uptimeMillis());
11213
11214        synchronized(this) {
11215            // Make sure we have no pre-ready processes sitting around.
11216
11217            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11218                ResolveInfo ri = mContext.getPackageManager()
11219                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11220                                STOCK_PM_FLAGS);
11221                CharSequence errorMsg = null;
11222                if (ri != null) {
11223                    ActivityInfo ai = ri.activityInfo;
11224                    ApplicationInfo app = ai.applicationInfo;
11225                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11226                        mTopAction = Intent.ACTION_FACTORY_TEST;
11227                        mTopData = null;
11228                        mTopComponent = new ComponentName(app.packageName,
11229                                ai.name);
11230                    } else {
11231                        errorMsg = mContext.getResources().getText(
11232                                com.android.internal.R.string.factorytest_not_system);
11233                    }
11234                } else {
11235                    errorMsg = mContext.getResources().getText(
11236                            com.android.internal.R.string.factorytest_no_action);
11237                }
11238                if (errorMsg != null) {
11239                    mTopAction = null;
11240                    mTopData = null;
11241                    mTopComponent = null;
11242                    Message msg = Message.obtain();
11243                    msg.what = SHOW_FACTORY_ERROR_MSG;
11244                    msg.getData().putCharSequence("msg", errorMsg);
11245                    mHandler.sendMessage(msg);
11246                }
11247            }
11248        }
11249
11250        retrieveSettings();
11251        loadResourcesOnSystemReady();
11252
11253        synchronized (this) {
11254            readGrantedUriPermissionsLocked();
11255        }
11256
11257        if (goingCallback != null) goingCallback.run();
11258
11259        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11260                Integer.toString(mCurrentUserId), mCurrentUserId);
11261        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11262                Integer.toString(mCurrentUserId), mCurrentUserId);
11263        mSystemServiceManager.startUser(mCurrentUserId);
11264
11265        synchronized (this) {
11266            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11267                try {
11268                    List apps = AppGlobals.getPackageManager().
11269                        getPersistentApplications(STOCK_PM_FLAGS);
11270                    if (apps != null) {
11271                        int N = apps.size();
11272                        int i;
11273                        for (i=0; i<N; i++) {
11274                            ApplicationInfo info
11275                                = (ApplicationInfo)apps.get(i);
11276                            if (info != null &&
11277                                    !info.packageName.equals("android")) {
11278                                addAppLocked(info, false, null /* ABI override */);
11279                            }
11280                        }
11281                    }
11282                } catch (RemoteException ex) {
11283                    // pm is in same process, this will never happen.
11284                }
11285            }
11286
11287            // Start up initial activity.
11288            mBooting = true;
11289            startHomeActivityLocked(mCurrentUserId);
11290
11291            try {
11292                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11293                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11294                            + " data partition or your device will be unstable.");
11295                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11296                }
11297            } catch (RemoteException e) {
11298            }
11299
11300            if (!Build.isFingerprintConsistent()) {
11301                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11302                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11303            }
11304
11305            long ident = Binder.clearCallingIdentity();
11306            try {
11307                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11308                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11309                        | Intent.FLAG_RECEIVER_FOREGROUND);
11310                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11311                broadcastIntentLocked(null, null, intent,
11312                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11313                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11314                intent = new Intent(Intent.ACTION_USER_STARTING);
11315                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11316                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11317                broadcastIntentLocked(null, null, intent,
11318                        null, new IIntentReceiver.Stub() {
11319                            @Override
11320                            public void performReceive(Intent intent, int resultCode, String data,
11321                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11322                                    throws RemoteException {
11323                            }
11324                        }, 0, null, null,
11325                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11326                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11327            } catch (Throwable t) {
11328                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11329            } finally {
11330                Binder.restoreCallingIdentity(ident);
11331            }
11332            mStackSupervisor.resumeTopActivitiesLocked();
11333            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11334        }
11335    }
11336
11337    private boolean makeAppCrashingLocked(ProcessRecord app,
11338            String shortMsg, String longMsg, String stackTrace) {
11339        app.crashing = true;
11340        app.crashingReport = generateProcessError(app,
11341                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11342        startAppProblemLocked(app);
11343        app.stopFreezingAllLocked();
11344        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11345    }
11346
11347    private void makeAppNotRespondingLocked(ProcessRecord app,
11348            String activity, String shortMsg, String longMsg) {
11349        app.notResponding = true;
11350        app.notRespondingReport = generateProcessError(app,
11351                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11352                activity, shortMsg, longMsg, null);
11353        startAppProblemLocked(app);
11354        app.stopFreezingAllLocked();
11355    }
11356
11357    /**
11358     * Generate a process error record, suitable for attachment to a ProcessRecord.
11359     *
11360     * @param app The ProcessRecord in which the error occurred.
11361     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11362     *                      ActivityManager.AppErrorStateInfo
11363     * @param activity The activity associated with the crash, if known.
11364     * @param shortMsg Short message describing the crash.
11365     * @param longMsg Long message describing the crash.
11366     * @param stackTrace Full crash stack trace, may be null.
11367     *
11368     * @return Returns a fully-formed AppErrorStateInfo record.
11369     */
11370    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11371            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11372        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11373
11374        report.condition = condition;
11375        report.processName = app.processName;
11376        report.pid = app.pid;
11377        report.uid = app.info.uid;
11378        report.tag = activity;
11379        report.shortMsg = shortMsg;
11380        report.longMsg = longMsg;
11381        report.stackTrace = stackTrace;
11382
11383        return report;
11384    }
11385
11386    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11387        synchronized (this) {
11388            app.crashing = false;
11389            app.crashingReport = null;
11390            app.notResponding = false;
11391            app.notRespondingReport = null;
11392            if (app.anrDialog == fromDialog) {
11393                app.anrDialog = null;
11394            }
11395            if (app.waitDialog == fromDialog) {
11396                app.waitDialog = null;
11397            }
11398            if (app.pid > 0 && app.pid != MY_PID) {
11399                handleAppCrashLocked(app, null, null, null);
11400                app.kill("user request after error", true);
11401            }
11402        }
11403    }
11404
11405    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11406            String stackTrace) {
11407        long now = SystemClock.uptimeMillis();
11408
11409        Long crashTime;
11410        if (!app.isolated) {
11411            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11412        } else {
11413            crashTime = null;
11414        }
11415        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11416            // This process loses!
11417            Slog.w(TAG, "Process " + app.info.processName
11418                    + " has crashed too many times: killing!");
11419            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11420                    app.userId, app.info.processName, app.uid);
11421            mStackSupervisor.handleAppCrashLocked(app);
11422            if (!app.persistent) {
11423                // We don't want to start this process again until the user
11424                // explicitly does so...  but for persistent process, we really
11425                // need to keep it running.  If a persistent process is actually
11426                // repeatedly crashing, then badness for everyone.
11427                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11428                        app.info.processName);
11429                if (!app.isolated) {
11430                    // XXX We don't have a way to mark isolated processes
11431                    // as bad, since they don't have a peristent identity.
11432                    mBadProcesses.put(app.info.processName, app.uid,
11433                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11434                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11435                }
11436                app.bad = true;
11437                app.removed = true;
11438                // Don't let services in this process be restarted and potentially
11439                // annoy the user repeatedly.  Unless it is persistent, since those
11440                // processes run critical code.
11441                removeProcessLocked(app, false, false, "crash");
11442                mStackSupervisor.resumeTopActivitiesLocked();
11443                return false;
11444            }
11445            mStackSupervisor.resumeTopActivitiesLocked();
11446        } else {
11447            mStackSupervisor.finishTopRunningActivityLocked(app);
11448        }
11449
11450        // Bump up the crash count of any services currently running in the proc.
11451        for (int i=app.services.size()-1; i>=0; i--) {
11452            // Any services running in the application need to be placed
11453            // back in the pending list.
11454            ServiceRecord sr = app.services.valueAt(i);
11455            sr.crashCount++;
11456        }
11457
11458        // If the crashing process is what we consider to be the "home process" and it has been
11459        // replaced by a third-party app, clear the package preferred activities from packages
11460        // with a home activity running in the process to prevent a repeatedly crashing app
11461        // from blocking the user to manually clear the list.
11462        final ArrayList<ActivityRecord> activities = app.activities;
11463        if (app == mHomeProcess && activities.size() > 0
11464                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11465            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11466                final ActivityRecord r = activities.get(activityNdx);
11467                if (r.isHomeActivity()) {
11468                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11469                    try {
11470                        ActivityThread.getPackageManager()
11471                                .clearPackagePreferredActivities(r.packageName);
11472                    } catch (RemoteException c) {
11473                        // pm is in same process, this will never happen.
11474                    }
11475                }
11476            }
11477        }
11478
11479        if (!app.isolated) {
11480            // XXX Can't keep track of crash times for isolated processes,
11481            // because they don't have a perisistent identity.
11482            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11483        }
11484
11485        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11486        return true;
11487    }
11488
11489    void startAppProblemLocked(ProcessRecord app) {
11490        // If this app is not running under the current user, then we
11491        // can't give it a report button because that would require
11492        // launching the report UI under a different user.
11493        app.errorReportReceiver = null;
11494
11495        for (int userId : mCurrentProfileIds) {
11496            if (app.userId == userId) {
11497                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11498                        mContext, app.info.packageName, app.info.flags);
11499            }
11500        }
11501        skipCurrentReceiverLocked(app);
11502    }
11503
11504    void skipCurrentReceiverLocked(ProcessRecord app) {
11505        for (BroadcastQueue queue : mBroadcastQueues) {
11506            queue.skipCurrentReceiverLocked(app);
11507        }
11508    }
11509
11510    /**
11511     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11512     * The application process will exit immediately after this call returns.
11513     * @param app object of the crashing app, null for the system server
11514     * @param crashInfo describing the exception
11515     */
11516    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11517        ProcessRecord r = findAppProcess(app, "Crash");
11518        final String processName = app == null ? "system_server"
11519                : (r == null ? "unknown" : r.processName);
11520
11521        handleApplicationCrashInner("crash", r, processName, crashInfo);
11522    }
11523
11524    /* Native crash reporting uses this inner version because it needs to be somewhat
11525     * decoupled from the AM-managed cleanup lifecycle
11526     */
11527    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11528            ApplicationErrorReport.CrashInfo crashInfo) {
11529        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11530                UserHandle.getUserId(Binder.getCallingUid()), processName,
11531                r == null ? -1 : r.info.flags,
11532                crashInfo.exceptionClassName,
11533                crashInfo.exceptionMessage,
11534                crashInfo.throwFileName,
11535                crashInfo.throwLineNumber);
11536
11537        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11538
11539        crashApplication(r, crashInfo);
11540    }
11541
11542    public void handleApplicationStrictModeViolation(
11543            IBinder app,
11544            int violationMask,
11545            StrictMode.ViolationInfo info) {
11546        ProcessRecord r = findAppProcess(app, "StrictMode");
11547        if (r == null) {
11548            return;
11549        }
11550
11551        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11552            Integer stackFingerprint = info.hashCode();
11553            boolean logIt = true;
11554            synchronized (mAlreadyLoggedViolatedStacks) {
11555                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11556                    logIt = false;
11557                    // TODO: sub-sample into EventLog for these, with
11558                    // the info.durationMillis?  Then we'd get
11559                    // the relative pain numbers, without logging all
11560                    // the stack traces repeatedly.  We'd want to do
11561                    // likewise in the client code, which also does
11562                    // dup suppression, before the Binder call.
11563                } else {
11564                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11565                        mAlreadyLoggedViolatedStacks.clear();
11566                    }
11567                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11568                }
11569            }
11570            if (logIt) {
11571                logStrictModeViolationToDropBox(r, info);
11572            }
11573        }
11574
11575        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11576            AppErrorResult result = new AppErrorResult();
11577            synchronized (this) {
11578                final long origId = Binder.clearCallingIdentity();
11579
11580                Message msg = Message.obtain();
11581                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11582                HashMap<String, Object> data = new HashMap<String, Object>();
11583                data.put("result", result);
11584                data.put("app", r);
11585                data.put("violationMask", violationMask);
11586                data.put("info", info);
11587                msg.obj = data;
11588                mHandler.sendMessage(msg);
11589
11590                Binder.restoreCallingIdentity(origId);
11591            }
11592            int res = result.get();
11593            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11594        }
11595    }
11596
11597    // Depending on the policy in effect, there could be a bunch of
11598    // these in quick succession so we try to batch these together to
11599    // minimize disk writes, number of dropbox entries, and maximize
11600    // compression, by having more fewer, larger records.
11601    private void logStrictModeViolationToDropBox(
11602            ProcessRecord process,
11603            StrictMode.ViolationInfo info) {
11604        if (info == null) {
11605            return;
11606        }
11607        final boolean isSystemApp = process == null ||
11608                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11609                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11610        final String processName = process == null ? "unknown" : process.processName;
11611        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11612        final DropBoxManager dbox = (DropBoxManager)
11613                mContext.getSystemService(Context.DROPBOX_SERVICE);
11614
11615        // Exit early if the dropbox isn't configured to accept this report type.
11616        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11617
11618        boolean bufferWasEmpty;
11619        boolean needsFlush;
11620        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11621        synchronized (sb) {
11622            bufferWasEmpty = sb.length() == 0;
11623            appendDropBoxProcessHeaders(process, processName, sb);
11624            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11625            sb.append("System-App: ").append(isSystemApp).append("\n");
11626            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11627            if (info.violationNumThisLoop != 0) {
11628                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11629            }
11630            if (info.numAnimationsRunning != 0) {
11631                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11632            }
11633            if (info.broadcastIntentAction != null) {
11634                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11635            }
11636            if (info.durationMillis != -1) {
11637                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11638            }
11639            if (info.numInstances != -1) {
11640                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11641            }
11642            if (info.tags != null) {
11643                for (String tag : info.tags) {
11644                    sb.append("Span-Tag: ").append(tag).append("\n");
11645                }
11646            }
11647            sb.append("\n");
11648            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11649                sb.append(info.crashInfo.stackTrace);
11650            }
11651            sb.append("\n");
11652
11653            // Only buffer up to ~64k.  Various logging bits truncate
11654            // things at 128k.
11655            needsFlush = (sb.length() > 64 * 1024);
11656        }
11657
11658        // Flush immediately if the buffer's grown too large, or this
11659        // is a non-system app.  Non-system apps are isolated with a
11660        // different tag & policy and not batched.
11661        //
11662        // Batching is useful during internal testing with
11663        // StrictMode settings turned up high.  Without batching,
11664        // thousands of separate files could be created on boot.
11665        if (!isSystemApp || needsFlush) {
11666            new Thread("Error dump: " + dropboxTag) {
11667                @Override
11668                public void run() {
11669                    String report;
11670                    synchronized (sb) {
11671                        report = sb.toString();
11672                        sb.delete(0, sb.length());
11673                        sb.trimToSize();
11674                    }
11675                    if (report.length() != 0) {
11676                        dbox.addText(dropboxTag, report);
11677                    }
11678                }
11679            }.start();
11680            return;
11681        }
11682
11683        // System app batching:
11684        if (!bufferWasEmpty) {
11685            // An existing dropbox-writing thread is outstanding, so
11686            // we don't need to start it up.  The existing thread will
11687            // catch the buffer appends we just did.
11688            return;
11689        }
11690
11691        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11692        // (After this point, we shouldn't access AMS internal data structures.)
11693        new Thread("Error dump: " + dropboxTag) {
11694            @Override
11695            public void run() {
11696                // 5 second sleep to let stacks arrive and be batched together
11697                try {
11698                    Thread.sleep(5000);  // 5 seconds
11699                } catch (InterruptedException e) {}
11700
11701                String errorReport;
11702                synchronized (mStrictModeBuffer) {
11703                    errorReport = mStrictModeBuffer.toString();
11704                    if (errorReport.length() == 0) {
11705                        return;
11706                    }
11707                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11708                    mStrictModeBuffer.trimToSize();
11709                }
11710                dbox.addText(dropboxTag, errorReport);
11711            }
11712        }.start();
11713    }
11714
11715    /**
11716     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11717     * @param app object of the crashing app, null for the system server
11718     * @param tag reported by the caller
11719     * @param system whether this wtf is coming from the system
11720     * @param crashInfo describing the context of the error
11721     * @return true if the process should exit immediately (WTF is fatal)
11722     */
11723    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11724            final ApplicationErrorReport.CrashInfo crashInfo) {
11725        final int callingUid = Binder.getCallingUid();
11726        final int callingPid = Binder.getCallingPid();
11727
11728        if (system) {
11729            // If this is coming from the system, we could very well have low-level
11730            // system locks held, so we want to do this all asynchronously.  And we
11731            // never want this to become fatal, so there is that too.
11732            mHandler.post(new Runnable() {
11733                @Override public void run() {
11734                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11735                }
11736            });
11737            return false;
11738        }
11739
11740        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11741                crashInfo);
11742
11743        if (r != null && r.pid != Process.myPid() &&
11744                Settings.Global.getInt(mContext.getContentResolver(),
11745                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11746            crashApplication(r, crashInfo);
11747            return true;
11748        } else {
11749            return false;
11750        }
11751    }
11752
11753    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11754            final ApplicationErrorReport.CrashInfo crashInfo) {
11755        final ProcessRecord r = findAppProcess(app, "WTF");
11756        final String processName = app == null ? "system_server"
11757                : (r == null ? "unknown" : r.processName);
11758
11759        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11760                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11761
11762        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11763
11764        return r;
11765    }
11766
11767    /**
11768     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11769     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11770     */
11771    private ProcessRecord findAppProcess(IBinder app, String reason) {
11772        if (app == null) {
11773            return null;
11774        }
11775
11776        synchronized (this) {
11777            final int NP = mProcessNames.getMap().size();
11778            for (int ip=0; ip<NP; ip++) {
11779                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11780                final int NA = apps.size();
11781                for (int ia=0; ia<NA; ia++) {
11782                    ProcessRecord p = apps.valueAt(ia);
11783                    if (p.thread != null && p.thread.asBinder() == app) {
11784                        return p;
11785                    }
11786                }
11787            }
11788
11789            Slog.w(TAG, "Can't find mystery application for " + reason
11790                    + " from pid=" + Binder.getCallingPid()
11791                    + " uid=" + Binder.getCallingUid() + ": " + app);
11792            return null;
11793        }
11794    }
11795
11796    /**
11797     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11798     * to append various headers to the dropbox log text.
11799     */
11800    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11801            StringBuilder sb) {
11802        // Watchdog thread ends up invoking this function (with
11803        // a null ProcessRecord) to add the stack file to dropbox.
11804        // Do not acquire a lock on this (am) in such cases, as it
11805        // could cause a potential deadlock, if and when watchdog
11806        // is invoked due to unavailability of lock on am and it
11807        // would prevent watchdog from killing system_server.
11808        if (process == null) {
11809            sb.append("Process: ").append(processName).append("\n");
11810            return;
11811        }
11812        // Note: ProcessRecord 'process' is guarded by the service
11813        // instance.  (notably process.pkgList, which could otherwise change
11814        // concurrently during execution of this method)
11815        synchronized (this) {
11816            sb.append("Process: ").append(processName).append("\n");
11817            int flags = process.info.flags;
11818            IPackageManager pm = AppGlobals.getPackageManager();
11819            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11820            for (int ip=0; ip<process.pkgList.size(); ip++) {
11821                String pkg = process.pkgList.keyAt(ip);
11822                sb.append("Package: ").append(pkg);
11823                try {
11824                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11825                    if (pi != null) {
11826                        sb.append(" v").append(pi.versionCode);
11827                        if (pi.versionName != null) {
11828                            sb.append(" (").append(pi.versionName).append(")");
11829                        }
11830                    }
11831                } catch (RemoteException e) {
11832                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11833                }
11834                sb.append("\n");
11835            }
11836        }
11837    }
11838
11839    private static String processClass(ProcessRecord process) {
11840        if (process == null || process.pid == MY_PID) {
11841            return "system_server";
11842        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11843            return "system_app";
11844        } else {
11845            return "data_app";
11846        }
11847    }
11848
11849    /**
11850     * Write a description of an error (crash, WTF, ANR) to the drop box.
11851     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11852     * @param process which caused the error, null means the system server
11853     * @param activity which triggered the error, null if unknown
11854     * @param parent activity related to the error, null if unknown
11855     * @param subject line related to the error, null if absent
11856     * @param report in long form describing the error, null if absent
11857     * @param logFile to include in the report, null if none
11858     * @param crashInfo giving an application stack trace, null if absent
11859     */
11860    public void addErrorToDropBox(String eventType,
11861            ProcessRecord process, String processName, ActivityRecord activity,
11862            ActivityRecord parent, String subject,
11863            final String report, final File logFile,
11864            final ApplicationErrorReport.CrashInfo crashInfo) {
11865        // NOTE -- this must never acquire the ActivityManagerService lock,
11866        // otherwise the watchdog may be prevented from resetting the system.
11867
11868        final String dropboxTag = processClass(process) + "_" + eventType;
11869        final DropBoxManager dbox = (DropBoxManager)
11870                mContext.getSystemService(Context.DROPBOX_SERVICE);
11871
11872        // Exit early if the dropbox isn't configured to accept this report type.
11873        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11874
11875        final StringBuilder sb = new StringBuilder(1024);
11876        appendDropBoxProcessHeaders(process, processName, sb);
11877        if (activity != null) {
11878            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11879        }
11880        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11881            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11882        }
11883        if (parent != null && parent != activity) {
11884            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11885        }
11886        if (subject != null) {
11887            sb.append("Subject: ").append(subject).append("\n");
11888        }
11889        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11890        if (Debug.isDebuggerConnected()) {
11891            sb.append("Debugger: Connected\n");
11892        }
11893        sb.append("\n");
11894
11895        // Do the rest in a worker thread to avoid blocking the caller on I/O
11896        // (After this point, we shouldn't access AMS internal data structures.)
11897        Thread worker = new Thread("Error dump: " + dropboxTag) {
11898            @Override
11899            public void run() {
11900                if (report != null) {
11901                    sb.append(report);
11902                }
11903                if (logFile != null) {
11904                    try {
11905                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11906                                    "\n\n[[TRUNCATED]]"));
11907                    } catch (IOException e) {
11908                        Slog.e(TAG, "Error reading " + logFile, e);
11909                    }
11910                }
11911                if (crashInfo != null && crashInfo.stackTrace != null) {
11912                    sb.append(crashInfo.stackTrace);
11913                }
11914
11915                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11916                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11917                if (lines > 0) {
11918                    sb.append("\n");
11919
11920                    // Merge several logcat streams, and take the last N lines
11921                    InputStreamReader input = null;
11922                    try {
11923                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11924                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11925                                "-b", "crash",
11926                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11927
11928                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11929                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11930                        input = new InputStreamReader(logcat.getInputStream());
11931
11932                        int num;
11933                        char[] buf = new char[8192];
11934                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11935                    } catch (IOException e) {
11936                        Slog.e(TAG, "Error running logcat", e);
11937                    } finally {
11938                        if (input != null) try { input.close(); } catch (IOException e) {}
11939                    }
11940                }
11941
11942                dbox.addText(dropboxTag, sb.toString());
11943            }
11944        };
11945
11946        if (process == null) {
11947            // If process is null, we are being called from some internal code
11948            // and may be about to die -- run this synchronously.
11949            worker.run();
11950        } else {
11951            worker.start();
11952        }
11953    }
11954
11955    /**
11956     * Bring up the "unexpected error" dialog box for a crashing app.
11957     * Deal with edge cases (intercepts from instrumented applications,
11958     * ActivityController, error intent receivers, that sort of thing).
11959     * @param r the application crashing
11960     * @param crashInfo describing the failure
11961     */
11962    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11963        long timeMillis = System.currentTimeMillis();
11964        String shortMsg = crashInfo.exceptionClassName;
11965        String longMsg = crashInfo.exceptionMessage;
11966        String stackTrace = crashInfo.stackTrace;
11967        if (shortMsg != null && longMsg != null) {
11968            longMsg = shortMsg + ": " + longMsg;
11969        } else if (shortMsg != null) {
11970            longMsg = shortMsg;
11971        }
11972
11973        AppErrorResult result = new AppErrorResult();
11974        synchronized (this) {
11975            if (mController != null) {
11976                try {
11977                    String name = r != null ? r.processName : null;
11978                    int pid = r != null ? r.pid : Binder.getCallingPid();
11979                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11980                    if (!mController.appCrashed(name, pid,
11981                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11982                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11983                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11984                            Slog.w(TAG, "Skip killing native crashed app " + name
11985                                    + "(" + pid + ") during testing");
11986                        } else {
11987                            Slog.w(TAG, "Force-killing crashed app " + name
11988                                    + " at watcher's request");
11989                            if (r != null) {
11990                                r.kill("crash", true);
11991                            } else {
11992                                // Huh.
11993                                Process.killProcess(pid);
11994                                Process.killProcessGroup(uid, pid);
11995                            }
11996                        }
11997                        return;
11998                    }
11999                } catch (RemoteException e) {
12000                    mController = null;
12001                    Watchdog.getInstance().setActivityController(null);
12002                }
12003            }
12004
12005            final long origId = Binder.clearCallingIdentity();
12006
12007            // If this process is running instrumentation, finish it.
12008            if (r != null && r.instrumentationClass != null) {
12009                Slog.w(TAG, "Error in app " + r.processName
12010                      + " running instrumentation " + r.instrumentationClass + ":");
12011                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12012                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12013                Bundle info = new Bundle();
12014                info.putString("shortMsg", shortMsg);
12015                info.putString("longMsg", longMsg);
12016                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12017                Binder.restoreCallingIdentity(origId);
12018                return;
12019            }
12020
12021            // If we can't identify the process or it's already exceeded its crash quota,
12022            // quit right away without showing a crash dialog.
12023            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12024                Binder.restoreCallingIdentity(origId);
12025                return;
12026            }
12027
12028            Message msg = Message.obtain();
12029            msg.what = SHOW_ERROR_MSG;
12030            HashMap data = new HashMap();
12031            data.put("result", result);
12032            data.put("app", r);
12033            msg.obj = data;
12034            mHandler.sendMessage(msg);
12035
12036            Binder.restoreCallingIdentity(origId);
12037        }
12038
12039        int res = result.get();
12040
12041        Intent appErrorIntent = null;
12042        synchronized (this) {
12043            if (r != null && !r.isolated) {
12044                // XXX Can't keep track of crash time for isolated processes,
12045                // since they don't have a persistent identity.
12046                mProcessCrashTimes.put(r.info.processName, r.uid,
12047                        SystemClock.uptimeMillis());
12048            }
12049            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12050                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12051            }
12052        }
12053
12054        if (appErrorIntent != null) {
12055            try {
12056                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12057            } catch (ActivityNotFoundException e) {
12058                Slog.w(TAG, "bug report receiver dissappeared", e);
12059            }
12060        }
12061    }
12062
12063    Intent createAppErrorIntentLocked(ProcessRecord r,
12064            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12065        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12066        if (report == null) {
12067            return null;
12068        }
12069        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12070        result.setComponent(r.errorReportReceiver);
12071        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12072        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12073        return result;
12074    }
12075
12076    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12077            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12078        if (r.errorReportReceiver == null) {
12079            return null;
12080        }
12081
12082        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12083            return null;
12084        }
12085
12086        ApplicationErrorReport report = new ApplicationErrorReport();
12087        report.packageName = r.info.packageName;
12088        report.installerPackageName = r.errorReportReceiver.getPackageName();
12089        report.processName = r.processName;
12090        report.time = timeMillis;
12091        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12092
12093        if (r.crashing || r.forceCrashReport) {
12094            report.type = ApplicationErrorReport.TYPE_CRASH;
12095            report.crashInfo = crashInfo;
12096        } else if (r.notResponding) {
12097            report.type = ApplicationErrorReport.TYPE_ANR;
12098            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12099
12100            report.anrInfo.activity = r.notRespondingReport.tag;
12101            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12102            report.anrInfo.info = r.notRespondingReport.longMsg;
12103        }
12104
12105        return report;
12106    }
12107
12108    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12109        enforceNotIsolatedCaller("getProcessesInErrorState");
12110        // assume our apps are happy - lazy create the list
12111        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12112
12113        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12114                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12115        int userId = UserHandle.getUserId(Binder.getCallingUid());
12116
12117        synchronized (this) {
12118
12119            // iterate across all processes
12120            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12121                ProcessRecord app = mLruProcesses.get(i);
12122                if (!allUsers && app.userId != userId) {
12123                    continue;
12124                }
12125                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12126                    // This one's in trouble, so we'll generate a report for it
12127                    // crashes are higher priority (in case there's a crash *and* an anr)
12128                    ActivityManager.ProcessErrorStateInfo report = null;
12129                    if (app.crashing) {
12130                        report = app.crashingReport;
12131                    } else if (app.notResponding) {
12132                        report = app.notRespondingReport;
12133                    }
12134
12135                    if (report != null) {
12136                        if (errList == null) {
12137                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12138                        }
12139                        errList.add(report);
12140                    } else {
12141                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12142                                " crashing = " + app.crashing +
12143                                " notResponding = " + app.notResponding);
12144                    }
12145                }
12146            }
12147        }
12148
12149        return errList;
12150    }
12151
12152    static int procStateToImportance(int procState, int memAdj,
12153            ActivityManager.RunningAppProcessInfo currApp) {
12154        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12155        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12156            currApp.lru = memAdj;
12157        } else {
12158            currApp.lru = 0;
12159        }
12160        return imp;
12161    }
12162
12163    private void fillInProcMemInfo(ProcessRecord app,
12164            ActivityManager.RunningAppProcessInfo outInfo) {
12165        outInfo.pid = app.pid;
12166        outInfo.uid = app.info.uid;
12167        if (mHeavyWeightProcess == app) {
12168            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12169        }
12170        if (app.persistent) {
12171            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12172        }
12173        if (app.activities.size() > 0) {
12174            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12175        }
12176        outInfo.lastTrimLevel = app.trimMemoryLevel;
12177        int adj = app.curAdj;
12178        int procState = app.curProcState;
12179        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12180        outInfo.importanceReasonCode = app.adjTypeCode;
12181        outInfo.processState = app.curProcState;
12182    }
12183
12184    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12185        enforceNotIsolatedCaller("getRunningAppProcesses");
12186        // Lazy instantiation of list
12187        List<ActivityManager.RunningAppProcessInfo> runList = null;
12188        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12189                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12190        int userId = UserHandle.getUserId(Binder.getCallingUid());
12191        synchronized (this) {
12192            // Iterate across all processes
12193            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12194                ProcessRecord app = mLruProcesses.get(i);
12195                if (!allUsers && app.userId != userId) {
12196                    continue;
12197                }
12198                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12199                    // Generate process state info for running application
12200                    ActivityManager.RunningAppProcessInfo currApp =
12201                        new ActivityManager.RunningAppProcessInfo(app.processName,
12202                                app.pid, app.getPackageList());
12203                    fillInProcMemInfo(app, currApp);
12204                    if (app.adjSource instanceof ProcessRecord) {
12205                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12206                        currApp.importanceReasonImportance =
12207                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12208                                        app.adjSourceProcState);
12209                    } else if (app.adjSource instanceof ActivityRecord) {
12210                        ActivityRecord r = (ActivityRecord)app.adjSource;
12211                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12212                    }
12213                    if (app.adjTarget instanceof ComponentName) {
12214                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12215                    }
12216                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12217                    //        + " lru=" + currApp.lru);
12218                    if (runList == null) {
12219                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12220                    }
12221                    runList.add(currApp);
12222                }
12223            }
12224        }
12225        return runList;
12226    }
12227
12228    public List<ApplicationInfo> getRunningExternalApplications() {
12229        enforceNotIsolatedCaller("getRunningExternalApplications");
12230        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12231        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12232        if (runningApps != null && runningApps.size() > 0) {
12233            Set<String> extList = new HashSet<String>();
12234            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12235                if (app.pkgList != null) {
12236                    for (String pkg : app.pkgList) {
12237                        extList.add(pkg);
12238                    }
12239                }
12240            }
12241            IPackageManager pm = AppGlobals.getPackageManager();
12242            for (String pkg : extList) {
12243                try {
12244                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12245                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12246                        retList.add(info);
12247                    }
12248                } catch (RemoteException e) {
12249                }
12250            }
12251        }
12252        return retList;
12253    }
12254
12255    @Override
12256    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12257        enforceNotIsolatedCaller("getMyMemoryState");
12258        synchronized (this) {
12259            ProcessRecord proc;
12260            synchronized (mPidsSelfLocked) {
12261                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12262            }
12263            fillInProcMemInfo(proc, outInfo);
12264        }
12265    }
12266
12267    @Override
12268    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12269        if (checkCallingPermission(android.Manifest.permission.DUMP)
12270                != PackageManager.PERMISSION_GRANTED) {
12271            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12272                    + Binder.getCallingPid()
12273                    + ", uid=" + Binder.getCallingUid()
12274                    + " without permission "
12275                    + android.Manifest.permission.DUMP);
12276            return;
12277        }
12278
12279        boolean dumpAll = false;
12280        boolean dumpClient = false;
12281        String dumpPackage = null;
12282
12283        int opti = 0;
12284        while (opti < args.length) {
12285            String opt = args[opti];
12286            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12287                break;
12288            }
12289            opti++;
12290            if ("-a".equals(opt)) {
12291                dumpAll = true;
12292            } else if ("-c".equals(opt)) {
12293                dumpClient = true;
12294            } else if ("-h".equals(opt)) {
12295                pw.println("Activity manager dump options:");
12296                pw.println("  [-a] [-c] [-h] [cmd] ...");
12297                pw.println("  cmd may be one of:");
12298                pw.println("    a[ctivities]: activity stack state");
12299                pw.println("    r[recents]: recent activities state");
12300                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12301                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12302                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12303                pw.println("    o[om]: out of memory management");
12304                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12305                pw.println("    provider [COMP_SPEC]: provider client-side state");
12306                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12307                pw.println("    service [COMP_SPEC]: service client-side state");
12308                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12309                pw.println("    all: dump all activities");
12310                pw.println("    top: dump the top activity");
12311                pw.println("    write: write all pending state to storage");
12312                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12313                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12314                pw.println("    a partial substring in a component name, a");
12315                pw.println("    hex object identifier.");
12316                pw.println("  -a: include all available server state.");
12317                pw.println("  -c: include client state.");
12318                return;
12319            } else {
12320                pw.println("Unknown argument: " + opt + "; use -h for help");
12321            }
12322        }
12323
12324        long origId = Binder.clearCallingIdentity();
12325        boolean more = false;
12326        // Is the caller requesting to dump a particular piece of data?
12327        if (opti < args.length) {
12328            String cmd = args[opti];
12329            opti++;
12330            if ("activities".equals(cmd) || "a".equals(cmd)) {
12331                synchronized (this) {
12332                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12333                }
12334            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12335                synchronized (this) {
12336                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12337                }
12338            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12339                String[] newArgs;
12340                String name;
12341                if (opti >= args.length) {
12342                    name = null;
12343                    newArgs = EMPTY_STRING_ARRAY;
12344                } else {
12345                    name = args[opti];
12346                    opti++;
12347                    newArgs = new String[args.length - opti];
12348                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12349                            args.length - opti);
12350                }
12351                synchronized (this) {
12352                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12353                }
12354            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12355                String[] newArgs;
12356                String name;
12357                if (opti >= args.length) {
12358                    name = null;
12359                    newArgs = EMPTY_STRING_ARRAY;
12360                } else {
12361                    name = args[opti];
12362                    opti++;
12363                    newArgs = new String[args.length - opti];
12364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12365                            args.length - opti);
12366                }
12367                synchronized (this) {
12368                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12369                }
12370            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12371                String[] newArgs;
12372                String name;
12373                if (opti >= args.length) {
12374                    name = null;
12375                    newArgs = EMPTY_STRING_ARRAY;
12376                } else {
12377                    name = args[opti];
12378                    opti++;
12379                    newArgs = new String[args.length - opti];
12380                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12381                            args.length - opti);
12382                }
12383                synchronized (this) {
12384                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12385                }
12386            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12387                synchronized (this) {
12388                    dumpOomLocked(fd, pw, args, opti, true);
12389                }
12390            } else if ("provider".equals(cmd)) {
12391                String[] newArgs;
12392                String name;
12393                if (opti >= args.length) {
12394                    name = null;
12395                    newArgs = EMPTY_STRING_ARRAY;
12396                } else {
12397                    name = args[opti];
12398                    opti++;
12399                    newArgs = new String[args.length - opti];
12400                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12401                }
12402                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12403                    pw.println("No providers match: " + name);
12404                    pw.println("Use -h for help.");
12405                }
12406            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12407                synchronized (this) {
12408                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12409                }
12410            } else if ("service".equals(cmd)) {
12411                String[] newArgs;
12412                String name;
12413                if (opti >= args.length) {
12414                    name = null;
12415                    newArgs = EMPTY_STRING_ARRAY;
12416                } else {
12417                    name = args[opti];
12418                    opti++;
12419                    newArgs = new String[args.length - opti];
12420                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12421                            args.length - opti);
12422                }
12423                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12424                    pw.println("No services match: " + name);
12425                    pw.println("Use -h for help.");
12426                }
12427            } else if ("package".equals(cmd)) {
12428                String[] newArgs;
12429                if (opti >= args.length) {
12430                    pw.println("package: no package name specified");
12431                    pw.println("Use -h for help.");
12432                } else {
12433                    dumpPackage = args[opti];
12434                    opti++;
12435                    newArgs = new String[args.length - opti];
12436                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12437                            args.length - opti);
12438                    args = newArgs;
12439                    opti = 0;
12440                    more = true;
12441                }
12442            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12443                synchronized (this) {
12444                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12445                }
12446            } else if ("write".equals(cmd)) {
12447                mTaskPersister.flush();
12448                pw.println("All tasks persisted.");
12449                return;
12450            } else {
12451                // Dumping a single activity?
12452                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12453                    pw.println("Bad activity command, or no activities match: " + cmd);
12454                    pw.println("Use -h for help.");
12455                }
12456            }
12457            if (!more) {
12458                Binder.restoreCallingIdentity(origId);
12459                return;
12460            }
12461        }
12462
12463        // No piece of data specified, dump everything.
12464        synchronized (this) {
12465            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12466            pw.println();
12467            if (dumpAll) {
12468                pw.println("-------------------------------------------------------------------------------");
12469            }
12470            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12471            pw.println();
12472            if (dumpAll) {
12473                pw.println("-------------------------------------------------------------------------------");
12474            }
12475            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12476            pw.println();
12477            if (dumpAll) {
12478                pw.println("-------------------------------------------------------------------------------");
12479            }
12480            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12481            pw.println();
12482            if (dumpAll) {
12483                pw.println("-------------------------------------------------------------------------------");
12484            }
12485            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12486            pw.println();
12487            if (dumpAll) {
12488                pw.println("-------------------------------------------------------------------------------");
12489            }
12490            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12491            pw.println();
12492            if (dumpAll) {
12493                pw.println("-------------------------------------------------------------------------------");
12494            }
12495            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12496        }
12497        Binder.restoreCallingIdentity(origId);
12498    }
12499
12500    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12501            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12502        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12503
12504        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12505                dumpPackage);
12506        boolean needSep = printedAnything;
12507
12508        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12509                dumpPackage, needSep, "  mFocusedActivity: ");
12510        if (printed) {
12511            printedAnything = true;
12512            needSep = false;
12513        }
12514
12515        if (dumpPackage == null) {
12516            if (needSep) {
12517                pw.println();
12518            }
12519            needSep = true;
12520            printedAnything = true;
12521            mStackSupervisor.dump(pw, "  ");
12522        }
12523
12524        if (!printedAnything) {
12525            pw.println("  (nothing)");
12526        }
12527    }
12528
12529    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12530            int opti, boolean dumpAll, String dumpPackage) {
12531        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12532
12533        boolean printedAnything = false;
12534
12535        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12536            boolean printedHeader = false;
12537
12538            final int N = mRecentTasks.size();
12539            for (int i=0; i<N; i++) {
12540                TaskRecord tr = mRecentTasks.get(i);
12541                if (dumpPackage != null) {
12542                    if (tr.realActivity == null ||
12543                            !dumpPackage.equals(tr.realActivity)) {
12544                        continue;
12545                    }
12546                }
12547                if (!printedHeader) {
12548                    pw.println("  Recent tasks:");
12549                    printedHeader = true;
12550                    printedAnything = true;
12551                }
12552                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12553                        pw.println(tr);
12554                if (dumpAll) {
12555                    mRecentTasks.get(i).dump(pw, "    ");
12556                }
12557            }
12558        }
12559
12560        if (!printedAnything) {
12561            pw.println("  (nothing)");
12562        }
12563    }
12564
12565    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12566            int opti, boolean dumpAll, String dumpPackage) {
12567        boolean needSep = false;
12568        boolean printedAnything = false;
12569        int numPers = 0;
12570
12571        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12572
12573        if (dumpAll) {
12574            final int NP = mProcessNames.getMap().size();
12575            for (int ip=0; ip<NP; ip++) {
12576                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12577                final int NA = procs.size();
12578                for (int ia=0; ia<NA; ia++) {
12579                    ProcessRecord r = procs.valueAt(ia);
12580                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12581                        continue;
12582                    }
12583                    if (!needSep) {
12584                        pw.println("  All known processes:");
12585                        needSep = true;
12586                        printedAnything = true;
12587                    }
12588                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12589                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12590                        pw.print(" "); pw.println(r);
12591                    r.dump(pw, "    ");
12592                    if (r.persistent) {
12593                        numPers++;
12594                    }
12595                }
12596            }
12597        }
12598
12599        if (mIsolatedProcesses.size() > 0) {
12600            boolean printed = false;
12601            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12602                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12603                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12604                    continue;
12605                }
12606                if (!printed) {
12607                    if (needSep) {
12608                        pw.println();
12609                    }
12610                    pw.println("  Isolated process list (sorted by uid):");
12611                    printedAnything = true;
12612                    printed = true;
12613                    needSep = true;
12614                }
12615                pw.println(String.format("%sIsolated #%2d: %s",
12616                        "    ", i, r.toString()));
12617            }
12618        }
12619
12620        if (mLruProcesses.size() > 0) {
12621            if (needSep) {
12622                pw.println();
12623            }
12624            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12625                    pw.print(" total, non-act at ");
12626                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12627                    pw.print(", non-svc at ");
12628                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12629                    pw.println("):");
12630            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12631            needSep = true;
12632            printedAnything = true;
12633        }
12634
12635        if (dumpAll || dumpPackage != null) {
12636            synchronized (mPidsSelfLocked) {
12637                boolean printed = false;
12638                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12639                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12640                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12641                        continue;
12642                    }
12643                    if (!printed) {
12644                        if (needSep) pw.println();
12645                        needSep = true;
12646                        pw.println("  PID mappings:");
12647                        printed = true;
12648                        printedAnything = true;
12649                    }
12650                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12651                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12652                }
12653            }
12654        }
12655
12656        if (mForegroundProcesses.size() > 0) {
12657            synchronized (mPidsSelfLocked) {
12658                boolean printed = false;
12659                for (int i=0; i<mForegroundProcesses.size(); i++) {
12660                    ProcessRecord r = mPidsSelfLocked.get(
12661                            mForegroundProcesses.valueAt(i).pid);
12662                    if (dumpPackage != null && (r == null
12663                            || !r.pkgList.containsKey(dumpPackage))) {
12664                        continue;
12665                    }
12666                    if (!printed) {
12667                        if (needSep) pw.println();
12668                        needSep = true;
12669                        pw.println("  Foreground Processes:");
12670                        printed = true;
12671                        printedAnything = true;
12672                    }
12673                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12674                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12675                }
12676            }
12677        }
12678
12679        if (mPersistentStartingProcesses.size() > 0) {
12680            if (needSep) pw.println();
12681            needSep = true;
12682            printedAnything = true;
12683            pw.println("  Persisent processes that are starting:");
12684            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12685                    "Starting Norm", "Restarting PERS", dumpPackage);
12686        }
12687
12688        if (mRemovedProcesses.size() > 0) {
12689            if (needSep) pw.println();
12690            needSep = true;
12691            printedAnything = true;
12692            pw.println("  Processes that are being removed:");
12693            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12694                    "Removed Norm", "Removed PERS", dumpPackage);
12695        }
12696
12697        if (mProcessesOnHold.size() > 0) {
12698            if (needSep) pw.println();
12699            needSep = true;
12700            printedAnything = true;
12701            pw.println("  Processes that are on old until the system is ready:");
12702            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12703                    "OnHold Norm", "OnHold PERS", dumpPackage);
12704        }
12705
12706        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12707
12708        if (mProcessCrashTimes.getMap().size() > 0) {
12709            boolean printed = false;
12710            long now = SystemClock.uptimeMillis();
12711            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12712            final int NP = pmap.size();
12713            for (int ip=0; ip<NP; ip++) {
12714                String pname = pmap.keyAt(ip);
12715                SparseArray<Long> uids = pmap.valueAt(ip);
12716                final int N = uids.size();
12717                for (int i=0; i<N; i++) {
12718                    int puid = uids.keyAt(i);
12719                    ProcessRecord r = mProcessNames.get(pname, puid);
12720                    if (dumpPackage != null && (r == null
12721                            || !r.pkgList.containsKey(dumpPackage))) {
12722                        continue;
12723                    }
12724                    if (!printed) {
12725                        if (needSep) pw.println();
12726                        needSep = true;
12727                        pw.println("  Time since processes crashed:");
12728                        printed = true;
12729                        printedAnything = true;
12730                    }
12731                    pw.print("    Process "); pw.print(pname);
12732                            pw.print(" uid "); pw.print(puid);
12733                            pw.print(": last crashed ");
12734                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12735                            pw.println(" ago");
12736                }
12737            }
12738        }
12739
12740        if (mBadProcesses.getMap().size() > 0) {
12741            boolean printed = false;
12742            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12743            final int NP = pmap.size();
12744            for (int ip=0; ip<NP; ip++) {
12745                String pname = pmap.keyAt(ip);
12746                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12747                final int N = uids.size();
12748                for (int i=0; i<N; i++) {
12749                    int puid = uids.keyAt(i);
12750                    ProcessRecord r = mProcessNames.get(pname, puid);
12751                    if (dumpPackage != null && (r == null
12752                            || !r.pkgList.containsKey(dumpPackage))) {
12753                        continue;
12754                    }
12755                    if (!printed) {
12756                        if (needSep) pw.println();
12757                        needSep = true;
12758                        pw.println("  Bad processes:");
12759                        printedAnything = true;
12760                    }
12761                    BadProcessInfo info = uids.valueAt(i);
12762                    pw.print("    Bad process "); pw.print(pname);
12763                            pw.print(" uid "); pw.print(puid);
12764                            pw.print(": crashed at time "); pw.println(info.time);
12765                    if (info.shortMsg != null) {
12766                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12767                    }
12768                    if (info.longMsg != null) {
12769                        pw.print("      Long msg: "); pw.println(info.longMsg);
12770                    }
12771                    if (info.stack != null) {
12772                        pw.println("      Stack:");
12773                        int lastPos = 0;
12774                        for (int pos=0; pos<info.stack.length(); pos++) {
12775                            if (info.stack.charAt(pos) == '\n') {
12776                                pw.print("        ");
12777                                pw.write(info.stack, lastPos, pos-lastPos);
12778                                pw.println();
12779                                lastPos = pos+1;
12780                            }
12781                        }
12782                        if (lastPos < info.stack.length()) {
12783                            pw.print("        ");
12784                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12785                            pw.println();
12786                        }
12787                    }
12788                }
12789            }
12790        }
12791
12792        if (dumpPackage == null) {
12793            pw.println();
12794            needSep = false;
12795            pw.println("  mStartedUsers:");
12796            for (int i=0; i<mStartedUsers.size(); i++) {
12797                UserStartedState uss = mStartedUsers.valueAt(i);
12798                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12799                        pw.print(": "); uss.dump("", pw);
12800            }
12801            pw.print("  mStartedUserArray: [");
12802            for (int i=0; i<mStartedUserArray.length; i++) {
12803                if (i > 0) pw.print(", ");
12804                pw.print(mStartedUserArray[i]);
12805            }
12806            pw.println("]");
12807            pw.print("  mUserLru: [");
12808            for (int i=0; i<mUserLru.size(); i++) {
12809                if (i > 0) pw.print(", ");
12810                pw.print(mUserLru.get(i));
12811            }
12812            pw.println("]");
12813            if (dumpAll) {
12814                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12815            }
12816            synchronized (mUserProfileGroupIdsSelfLocked) {
12817                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12818                    pw.println("  mUserProfileGroupIds:");
12819                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12820                        pw.print("    User #");
12821                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12822                        pw.print(" -> profile #");
12823                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12824                    }
12825                }
12826            }
12827        }
12828        if (mHomeProcess != null && (dumpPackage == null
12829                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12830            if (needSep) {
12831                pw.println();
12832                needSep = false;
12833            }
12834            pw.println("  mHomeProcess: " + mHomeProcess);
12835        }
12836        if (mPreviousProcess != null && (dumpPackage == null
12837                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12838            if (needSep) {
12839                pw.println();
12840                needSep = false;
12841            }
12842            pw.println("  mPreviousProcess: " + mPreviousProcess);
12843        }
12844        if (dumpAll) {
12845            StringBuilder sb = new StringBuilder(128);
12846            sb.append("  mPreviousProcessVisibleTime: ");
12847            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12848            pw.println(sb);
12849        }
12850        if (mHeavyWeightProcess != null && (dumpPackage == null
12851                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12852            if (needSep) {
12853                pw.println();
12854                needSep = false;
12855            }
12856            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12857        }
12858        if (dumpPackage == null) {
12859            pw.println("  mConfiguration: " + mConfiguration);
12860        }
12861        if (dumpAll) {
12862            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12863            if (mCompatModePackages.getPackages().size() > 0) {
12864                boolean printed = false;
12865                for (Map.Entry<String, Integer> entry
12866                        : mCompatModePackages.getPackages().entrySet()) {
12867                    String pkg = entry.getKey();
12868                    int mode = entry.getValue();
12869                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12870                        continue;
12871                    }
12872                    if (!printed) {
12873                        pw.println("  mScreenCompatPackages:");
12874                        printed = true;
12875                    }
12876                    pw.print("    "); pw.print(pkg); pw.print(": ");
12877                            pw.print(mode); pw.println();
12878                }
12879            }
12880        }
12881        if (dumpPackage == null) {
12882            pw.println("  mWakefulness="
12883                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12884            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12885                    + lockScreenShownToString());
12886            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12887        }
12888        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12889                || mOrigWaitForDebugger) {
12890            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12891                    || dumpPackage.equals(mOrigDebugApp)) {
12892                if (needSep) {
12893                    pw.println();
12894                    needSep = false;
12895                }
12896                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12897                        + " mDebugTransient=" + mDebugTransient
12898                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12899            }
12900        }
12901        if (mOpenGlTraceApp != null) {
12902            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12903                if (needSep) {
12904                    pw.println();
12905                    needSep = false;
12906                }
12907                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12908            }
12909        }
12910        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12911                || mProfileFd != null) {
12912            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12913                if (needSep) {
12914                    pw.println();
12915                    needSep = false;
12916                }
12917                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12918                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12919                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12920                        + mAutoStopProfiler);
12921                pw.println("  mProfileType=" + mProfileType);
12922            }
12923        }
12924        if (dumpPackage == null) {
12925            if (mAlwaysFinishActivities || mController != null) {
12926                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12927                        + " mController=" + mController);
12928            }
12929            if (dumpAll) {
12930                pw.println("  Total persistent processes: " + numPers);
12931                pw.println("  mProcessesReady=" + mProcessesReady
12932                        + " mSystemReady=" + mSystemReady
12933                        + " mBooted=" + mBooted
12934                        + " mFactoryTest=" + mFactoryTest);
12935                pw.println("  mBooting=" + mBooting
12936                        + " mCallFinishBooting=" + mCallFinishBooting
12937                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12938                pw.print("  mLastPowerCheckRealtime=");
12939                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12940                        pw.println("");
12941                pw.print("  mLastPowerCheckUptime=");
12942                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12943                        pw.println("");
12944                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12945                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12946                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12947                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12948                        + " (" + mLruProcesses.size() + " total)"
12949                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12950                        + " mNumServiceProcs=" + mNumServiceProcs
12951                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12952                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12953                        + " mLastMemoryLevel" + mLastMemoryLevel
12954                        + " mLastNumProcesses" + mLastNumProcesses);
12955                long now = SystemClock.uptimeMillis();
12956                pw.print("  mLastIdleTime=");
12957                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12958                        pw.print(" mLowRamSinceLastIdle=");
12959                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12960                        pw.println();
12961            }
12962        }
12963
12964        if (!printedAnything) {
12965            pw.println("  (nothing)");
12966        }
12967    }
12968
12969    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12970            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12971        if (mProcessesToGc.size() > 0) {
12972            boolean printed = false;
12973            long now = SystemClock.uptimeMillis();
12974            for (int i=0; i<mProcessesToGc.size(); i++) {
12975                ProcessRecord proc = mProcessesToGc.get(i);
12976                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12977                    continue;
12978                }
12979                if (!printed) {
12980                    if (needSep) pw.println();
12981                    needSep = true;
12982                    pw.println("  Processes that are waiting to GC:");
12983                    printed = true;
12984                }
12985                pw.print("    Process "); pw.println(proc);
12986                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12987                        pw.print(", last gced=");
12988                        pw.print(now-proc.lastRequestedGc);
12989                        pw.print(" ms ago, last lowMem=");
12990                        pw.print(now-proc.lastLowMemory);
12991                        pw.println(" ms ago");
12992
12993            }
12994        }
12995        return needSep;
12996    }
12997
12998    void printOomLevel(PrintWriter pw, String name, int adj) {
12999        pw.print("    ");
13000        if (adj >= 0) {
13001            pw.print(' ');
13002            if (adj < 10) pw.print(' ');
13003        } else {
13004            if (adj > -10) pw.print(' ');
13005        }
13006        pw.print(adj);
13007        pw.print(": ");
13008        pw.print(name);
13009        pw.print(" (");
13010        pw.print(mProcessList.getMemLevel(adj)/1024);
13011        pw.println(" kB)");
13012    }
13013
13014    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13015            int opti, boolean dumpAll) {
13016        boolean needSep = false;
13017
13018        if (mLruProcesses.size() > 0) {
13019            if (needSep) pw.println();
13020            needSep = true;
13021            pw.println("  OOM levels:");
13022            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13023            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13024            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13025            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13026            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13027            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13028            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13029            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13030            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13031            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13032            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13033            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13034            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13035            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13036
13037            if (needSep) pw.println();
13038            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13039                    pw.print(" total, non-act at ");
13040                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13041                    pw.print(", non-svc at ");
13042                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13043                    pw.println("):");
13044            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13045            needSep = true;
13046        }
13047
13048        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13049
13050        pw.println();
13051        pw.println("  mHomeProcess: " + mHomeProcess);
13052        pw.println("  mPreviousProcess: " + mPreviousProcess);
13053        if (mHeavyWeightProcess != null) {
13054            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13055        }
13056
13057        return true;
13058    }
13059
13060    /**
13061     * There are three ways to call this:
13062     *  - no provider specified: dump all the providers
13063     *  - a flattened component name that matched an existing provider was specified as the
13064     *    first arg: dump that one provider
13065     *  - the first arg isn't the flattened component name of an existing provider:
13066     *    dump all providers whose component contains the first arg as a substring
13067     */
13068    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13069            int opti, boolean dumpAll) {
13070        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13071    }
13072
13073    static class ItemMatcher {
13074        ArrayList<ComponentName> components;
13075        ArrayList<String> strings;
13076        ArrayList<Integer> objects;
13077        boolean all;
13078
13079        ItemMatcher() {
13080            all = true;
13081        }
13082
13083        void build(String name) {
13084            ComponentName componentName = ComponentName.unflattenFromString(name);
13085            if (componentName != null) {
13086                if (components == null) {
13087                    components = new ArrayList<ComponentName>();
13088                }
13089                components.add(componentName);
13090                all = false;
13091            } else {
13092                int objectId = 0;
13093                // Not a '/' separated full component name; maybe an object ID?
13094                try {
13095                    objectId = Integer.parseInt(name, 16);
13096                    if (objects == null) {
13097                        objects = new ArrayList<Integer>();
13098                    }
13099                    objects.add(objectId);
13100                    all = false;
13101                } catch (RuntimeException e) {
13102                    // Not an integer; just do string match.
13103                    if (strings == null) {
13104                        strings = new ArrayList<String>();
13105                    }
13106                    strings.add(name);
13107                    all = false;
13108                }
13109            }
13110        }
13111
13112        int build(String[] args, int opti) {
13113            for (; opti<args.length; opti++) {
13114                String name = args[opti];
13115                if ("--".equals(name)) {
13116                    return opti+1;
13117                }
13118                build(name);
13119            }
13120            return opti;
13121        }
13122
13123        boolean match(Object object, ComponentName comp) {
13124            if (all) {
13125                return true;
13126            }
13127            if (components != null) {
13128                for (int i=0; i<components.size(); i++) {
13129                    if (components.get(i).equals(comp)) {
13130                        return true;
13131                    }
13132                }
13133            }
13134            if (objects != null) {
13135                for (int i=0; i<objects.size(); i++) {
13136                    if (System.identityHashCode(object) == objects.get(i)) {
13137                        return true;
13138                    }
13139                }
13140            }
13141            if (strings != null) {
13142                String flat = comp.flattenToString();
13143                for (int i=0; i<strings.size(); i++) {
13144                    if (flat.contains(strings.get(i))) {
13145                        return true;
13146                    }
13147                }
13148            }
13149            return false;
13150        }
13151    }
13152
13153    /**
13154     * There are three things that cmd can be:
13155     *  - a flattened component name that matches an existing activity
13156     *  - the cmd arg isn't the flattened component name of an existing activity:
13157     *    dump all activity whose component contains the cmd as a substring
13158     *  - A hex number of the ActivityRecord object instance.
13159     */
13160    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13161            int opti, boolean dumpAll) {
13162        ArrayList<ActivityRecord> activities;
13163
13164        synchronized (this) {
13165            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13166        }
13167
13168        if (activities.size() <= 0) {
13169            return false;
13170        }
13171
13172        String[] newArgs = new String[args.length - opti];
13173        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13174
13175        TaskRecord lastTask = null;
13176        boolean needSep = false;
13177        for (int i=activities.size()-1; i>=0; i--) {
13178            ActivityRecord r = activities.get(i);
13179            if (needSep) {
13180                pw.println();
13181            }
13182            needSep = true;
13183            synchronized (this) {
13184                if (lastTask != r.task) {
13185                    lastTask = r.task;
13186                    pw.print("TASK "); pw.print(lastTask.affinity);
13187                            pw.print(" id="); pw.println(lastTask.taskId);
13188                    if (dumpAll) {
13189                        lastTask.dump(pw, "  ");
13190                    }
13191                }
13192            }
13193            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13194        }
13195        return true;
13196    }
13197
13198    /**
13199     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13200     * there is a thread associated with the activity.
13201     */
13202    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13203            final ActivityRecord r, String[] args, boolean dumpAll) {
13204        String innerPrefix = prefix + "  ";
13205        synchronized (this) {
13206            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13207                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13208                    pw.print(" pid=");
13209                    if (r.app != null) pw.println(r.app.pid);
13210                    else pw.println("(not running)");
13211            if (dumpAll) {
13212                r.dump(pw, innerPrefix);
13213            }
13214        }
13215        if (r.app != null && r.app.thread != null) {
13216            // flush anything that is already in the PrintWriter since the thread is going
13217            // to write to the file descriptor directly
13218            pw.flush();
13219            try {
13220                TransferPipe tp = new TransferPipe();
13221                try {
13222                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13223                            r.appToken, innerPrefix, args);
13224                    tp.go(fd);
13225                } finally {
13226                    tp.kill();
13227                }
13228            } catch (IOException e) {
13229                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13230            } catch (RemoteException e) {
13231                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13232            }
13233        }
13234    }
13235
13236    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13237            int opti, boolean dumpAll, String dumpPackage) {
13238        boolean needSep = false;
13239        boolean onlyHistory = false;
13240        boolean printedAnything = false;
13241
13242        if ("history".equals(dumpPackage)) {
13243            if (opti < args.length && "-s".equals(args[opti])) {
13244                dumpAll = false;
13245            }
13246            onlyHistory = true;
13247            dumpPackage = null;
13248        }
13249
13250        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13251        if (!onlyHistory && dumpAll) {
13252            if (mRegisteredReceivers.size() > 0) {
13253                boolean printed = false;
13254                Iterator it = mRegisteredReceivers.values().iterator();
13255                while (it.hasNext()) {
13256                    ReceiverList r = (ReceiverList)it.next();
13257                    if (dumpPackage != null && (r.app == null ||
13258                            !dumpPackage.equals(r.app.info.packageName))) {
13259                        continue;
13260                    }
13261                    if (!printed) {
13262                        pw.println("  Registered Receivers:");
13263                        needSep = true;
13264                        printed = true;
13265                        printedAnything = true;
13266                    }
13267                    pw.print("  * "); pw.println(r);
13268                    r.dump(pw, "    ");
13269                }
13270            }
13271
13272            if (mReceiverResolver.dump(pw, needSep ?
13273                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13274                    "    ", dumpPackage, false, false)) {
13275                needSep = true;
13276                printedAnything = true;
13277            }
13278        }
13279
13280        for (BroadcastQueue q : mBroadcastQueues) {
13281            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13282            printedAnything |= needSep;
13283        }
13284
13285        needSep = true;
13286
13287        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13288            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13289                if (needSep) {
13290                    pw.println();
13291                }
13292                needSep = true;
13293                printedAnything = true;
13294                pw.print("  Sticky broadcasts for user ");
13295                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13296                StringBuilder sb = new StringBuilder(128);
13297                for (Map.Entry<String, ArrayList<Intent>> ent
13298                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13299                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13300                    if (dumpAll) {
13301                        pw.println(":");
13302                        ArrayList<Intent> intents = ent.getValue();
13303                        final int N = intents.size();
13304                        for (int i=0; i<N; i++) {
13305                            sb.setLength(0);
13306                            sb.append("    Intent: ");
13307                            intents.get(i).toShortString(sb, false, true, false, false);
13308                            pw.println(sb.toString());
13309                            Bundle bundle = intents.get(i).getExtras();
13310                            if (bundle != null) {
13311                                pw.print("      ");
13312                                pw.println(bundle.toString());
13313                            }
13314                        }
13315                    } else {
13316                        pw.println("");
13317                    }
13318                }
13319            }
13320        }
13321
13322        if (!onlyHistory && dumpAll) {
13323            pw.println();
13324            for (BroadcastQueue queue : mBroadcastQueues) {
13325                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13326                        + queue.mBroadcastsScheduled);
13327            }
13328            pw.println("  mHandler:");
13329            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13330            needSep = true;
13331            printedAnything = true;
13332        }
13333
13334        if (!printedAnything) {
13335            pw.println("  (nothing)");
13336        }
13337    }
13338
13339    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13340            int opti, boolean dumpAll, String dumpPackage) {
13341        boolean needSep;
13342        boolean printedAnything = false;
13343
13344        ItemMatcher matcher = new ItemMatcher();
13345        matcher.build(args, opti);
13346
13347        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13348
13349        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13350        printedAnything |= needSep;
13351
13352        if (mLaunchingProviders.size() > 0) {
13353            boolean printed = false;
13354            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13355                ContentProviderRecord r = mLaunchingProviders.get(i);
13356                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13357                    continue;
13358                }
13359                if (!printed) {
13360                    if (needSep) pw.println();
13361                    needSep = true;
13362                    pw.println("  Launching content providers:");
13363                    printed = true;
13364                    printedAnything = true;
13365                }
13366                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13367                        pw.println(r);
13368            }
13369        }
13370
13371        if (mGrantedUriPermissions.size() > 0) {
13372            boolean printed = false;
13373            int dumpUid = -2;
13374            if (dumpPackage != null) {
13375                try {
13376                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13377                } catch (NameNotFoundException e) {
13378                    dumpUid = -1;
13379                }
13380            }
13381            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13382                int uid = mGrantedUriPermissions.keyAt(i);
13383                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13384                    continue;
13385                }
13386                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13387                if (!printed) {
13388                    if (needSep) pw.println();
13389                    needSep = true;
13390                    pw.println("  Granted Uri Permissions:");
13391                    printed = true;
13392                    printedAnything = true;
13393                }
13394                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13395                for (UriPermission perm : perms.values()) {
13396                    pw.print("    "); pw.println(perm);
13397                    if (dumpAll) {
13398                        perm.dump(pw, "      ");
13399                    }
13400                }
13401            }
13402        }
13403
13404        if (!printedAnything) {
13405            pw.println("  (nothing)");
13406        }
13407    }
13408
13409    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13410            int opti, boolean dumpAll, String dumpPackage) {
13411        boolean printed = false;
13412
13413        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13414
13415        if (mIntentSenderRecords.size() > 0) {
13416            Iterator<WeakReference<PendingIntentRecord>> it
13417                    = mIntentSenderRecords.values().iterator();
13418            while (it.hasNext()) {
13419                WeakReference<PendingIntentRecord> ref = it.next();
13420                PendingIntentRecord rec = ref != null ? ref.get(): null;
13421                if (dumpPackage != null && (rec == null
13422                        || !dumpPackage.equals(rec.key.packageName))) {
13423                    continue;
13424                }
13425                printed = true;
13426                if (rec != null) {
13427                    pw.print("  * "); pw.println(rec);
13428                    if (dumpAll) {
13429                        rec.dump(pw, "    ");
13430                    }
13431                } else {
13432                    pw.print("  * "); pw.println(ref);
13433                }
13434            }
13435        }
13436
13437        if (!printed) {
13438            pw.println("  (nothing)");
13439        }
13440    }
13441
13442    private static final int dumpProcessList(PrintWriter pw,
13443            ActivityManagerService service, List list,
13444            String prefix, String normalLabel, String persistentLabel,
13445            String dumpPackage) {
13446        int numPers = 0;
13447        final int N = list.size()-1;
13448        for (int i=N; i>=0; i--) {
13449            ProcessRecord r = (ProcessRecord)list.get(i);
13450            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13451                continue;
13452            }
13453            pw.println(String.format("%s%s #%2d: %s",
13454                    prefix, (r.persistent ? persistentLabel : normalLabel),
13455                    i, r.toString()));
13456            if (r.persistent) {
13457                numPers++;
13458            }
13459        }
13460        return numPers;
13461    }
13462
13463    private static final boolean dumpProcessOomList(PrintWriter pw,
13464            ActivityManagerService service, List<ProcessRecord> origList,
13465            String prefix, String normalLabel, String persistentLabel,
13466            boolean inclDetails, String dumpPackage) {
13467
13468        ArrayList<Pair<ProcessRecord, Integer>> list
13469                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13470        for (int i=0; i<origList.size(); i++) {
13471            ProcessRecord r = origList.get(i);
13472            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13473                continue;
13474            }
13475            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13476        }
13477
13478        if (list.size() <= 0) {
13479            return false;
13480        }
13481
13482        Comparator<Pair<ProcessRecord, Integer>> comparator
13483                = new Comparator<Pair<ProcessRecord, Integer>>() {
13484            @Override
13485            public int compare(Pair<ProcessRecord, Integer> object1,
13486                    Pair<ProcessRecord, Integer> object2) {
13487                if (object1.first.setAdj != object2.first.setAdj) {
13488                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13489                }
13490                if (object1.second.intValue() != object2.second.intValue()) {
13491                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13492                }
13493                return 0;
13494            }
13495        };
13496
13497        Collections.sort(list, comparator);
13498
13499        final long curRealtime = SystemClock.elapsedRealtime();
13500        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13501        final long curUptime = SystemClock.uptimeMillis();
13502        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13503
13504        for (int i=list.size()-1; i>=0; i--) {
13505            ProcessRecord r = list.get(i).first;
13506            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13507            char schedGroup;
13508            switch (r.setSchedGroup) {
13509                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13510                    schedGroup = 'B';
13511                    break;
13512                case Process.THREAD_GROUP_DEFAULT:
13513                    schedGroup = 'F';
13514                    break;
13515                default:
13516                    schedGroup = '?';
13517                    break;
13518            }
13519            char foreground;
13520            if (r.foregroundActivities) {
13521                foreground = 'A';
13522            } else if (r.foregroundServices) {
13523                foreground = 'S';
13524            } else {
13525                foreground = ' ';
13526            }
13527            String procState = ProcessList.makeProcStateString(r.curProcState);
13528            pw.print(prefix);
13529            pw.print(r.persistent ? persistentLabel : normalLabel);
13530            pw.print(" #");
13531            int num = (origList.size()-1)-list.get(i).second;
13532            if (num < 10) pw.print(' ');
13533            pw.print(num);
13534            pw.print(": ");
13535            pw.print(oomAdj);
13536            pw.print(' ');
13537            pw.print(schedGroup);
13538            pw.print('/');
13539            pw.print(foreground);
13540            pw.print('/');
13541            pw.print(procState);
13542            pw.print(" trm:");
13543            if (r.trimMemoryLevel < 10) pw.print(' ');
13544            pw.print(r.trimMemoryLevel);
13545            pw.print(' ');
13546            pw.print(r.toShortString());
13547            pw.print(" (");
13548            pw.print(r.adjType);
13549            pw.println(')');
13550            if (r.adjSource != null || r.adjTarget != null) {
13551                pw.print(prefix);
13552                pw.print("    ");
13553                if (r.adjTarget instanceof ComponentName) {
13554                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13555                } else if (r.adjTarget != null) {
13556                    pw.print(r.adjTarget.toString());
13557                } else {
13558                    pw.print("{null}");
13559                }
13560                pw.print("<=");
13561                if (r.adjSource instanceof ProcessRecord) {
13562                    pw.print("Proc{");
13563                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13564                    pw.println("}");
13565                } else if (r.adjSource != null) {
13566                    pw.println(r.adjSource.toString());
13567                } else {
13568                    pw.println("{null}");
13569                }
13570            }
13571            if (inclDetails) {
13572                pw.print(prefix);
13573                pw.print("    ");
13574                pw.print("oom: max="); pw.print(r.maxAdj);
13575                pw.print(" curRaw="); pw.print(r.curRawAdj);
13576                pw.print(" setRaw="); pw.print(r.setRawAdj);
13577                pw.print(" cur="); pw.print(r.curAdj);
13578                pw.print(" set="); pw.println(r.setAdj);
13579                pw.print(prefix);
13580                pw.print("    ");
13581                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13582                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13583                pw.print(" lastPss="); pw.print(r.lastPss);
13584                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13585                pw.print(prefix);
13586                pw.print("    ");
13587                pw.print("cached="); pw.print(r.cached);
13588                pw.print(" empty="); pw.print(r.empty);
13589                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13590
13591                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13592                    if (r.lastWakeTime != 0) {
13593                        long wtime;
13594                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13595                        synchronized (stats) {
13596                            wtime = stats.getProcessWakeTime(r.info.uid,
13597                                    r.pid, curRealtime);
13598                        }
13599                        long timeUsed = wtime - r.lastWakeTime;
13600                        pw.print(prefix);
13601                        pw.print("    ");
13602                        pw.print("keep awake over ");
13603                        TimeUtils.formatDuration(realtimeSince, pw);
13604                        pw.print(" used ");
13605                        TimeUtils.formatDuration(timeUsed, pw);
13606                        pw.print(" (");
13607                        pw.print((timeUsed*100)/realtimeSince);
13608                        pw.println("%)");
13609                    }
13610                    if (r.lastCpuTime != 0) {
13611                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13612                        pw.print(prefix);
13613                        pw.print("    ");
13614                        pw.print("run cpu over ");
13615                        TimeUtils.formatDuration(uptimeSince, pw);
13616                        pw.print(" used ");
13617                        TimeUtils.formatDuration(timeUsed, pw);
13618                        pw.print(" (");
13619                        pw.print((timeUsed*100)/uptimeSince);
13620                        pw.println("%)");
13621                    }
13622                }
13623            }
13624        }
13625        return true;
13626    }
13627
13628    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13629            String[] args) {
13630        ArrayList<ProcessRecord> procs;
13631        synchronized (this) {
13632            if (args != null && args.length > start
13633                    && args[start].charAt(0) != '-') {
13634                procs = new ArrayList<ProcessRecord>();
13635                int pid = -1;
13636                try {
13637                    pid = Integer.parseInt(args[start]);
13638                } catch (NumberFormatException e) {
13639                }
13640                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13641                    ProcessRecord proc = mLruProcesses.get(i);
13642                    if (proc.pid == pid) {
13643                        procs.add(proc);
13644                    } else if (allPkgs && proc.pkgList != null
13645                            && proc.pkgList.containsKey(args[start])) {
13646                        procs.add(proc);
13647                    } else if (proc.processName.equals(args[start])) {
13648                        procs.add(proc);
13649                    }
13650                }
13651                if (procs.size() <= 0) {
13652                    return null;
13653                }
13654            } else {
13655                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13656            }
13657        }
13658        return procs;
13659    }
13660
13661    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13662            PrintWriter pw, String[] args) {
13663        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13664        if (procs == null) {
13665            pw.println("No process found for: " + args[0]);
13666            return;
13667        }
13668
13669        long uptime = SystemClock.uptimeMillis();
13670        long realtime = SystemClock.elapsedRealtime();
13671        pw.println("Applications Graphics Acceleration Info:");
13672        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13673
13674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13675            ProcessRecord r = procs.get(i);
13676            if (r.thread != null) {
13677                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13678                pw.flush();
13679                try {
13680                    TransferPipe tp = new TransferPipe();
13681                    try {
13682                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13683                        tp.go(fd);
13684                    } finally {
13685                        tp.kill();
13686                    }
13687                } catch (IOException e) {
13688                    pw.println("Failure while dumping the app: " + r);
13689                    pw.flush();
13690                } catch (RemoteException e) {
13691                    pw.println("Got a RemoteException while dumping the app " + r);
13692                    pw.flush();
13693                }
13694            }
13695        }
13696    }
13697
13698    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13699        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13700        if (procs == null) {
13701            pw.println("No process found for: " + args[0]);
13702            return;
13703        }
13704
13705        pw.println("Applications Database Info:");
13706
13707        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13708            ProcessRecord r = procs.get(i);
13709            if (r.thread != null) {
13710                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13711                pw.flush();
13712                try {
13713                    TransferPipe tp = new TransferPipe();
13714                    try {
13715                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13716                        tp.go(fd);
13717                    } finally {
13718                        tp.kill();
13719                    }
13720                } catch (IOException e) {
13721                    pw.println("Failure while dumping the app: " + r);
13722                    pw.flush();
13723                } catch (RemoteException e) {
13724                    pw.println("Got a RemoteException while dumping the app " + r);
13725                    pw.flush();
13726                }
13727            }
13728        }
13729    }
13730
13731    final static class MemItem {
13732        final boolean isProc;
13733        final String label;
13734        final String shortLabel;
13735        final long pss;
13736        final int id;
13737        final boolean hasActivities;
13738        ArrayList<MemItem> subitems;
13739
13740        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13741                boolean _hasActivities) {
13742            isProc = true;
13743            label = _label;
13744            shortLabel = _shortLabel;
13745            pss = _pss;
13746            id = _id;
13747            hasActivities = _hasActivities;
13748        }
13749
13750        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13751            isProc = false;
13752            label = _label;
13753            shortLabel = _shortLabel;
13754            pss = _pss;
13755            id = _id;
13756            hasActivities = false;
13757        }
13758    }
13759
13760    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13761            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13762        if (sort && !isCompact) {
13763            Collections.sort(items, new Comparator<MemItem>() {
13764                @Override
13765                public int compare(MemItem lhs, MemItem rhs) {
13766                    if (lhs.pss < rhs.pss) {
13767                        return 1;
13768                    } else if (lhs.pss > rhs.pss) {
13769                        return -1;
13770                    }
13771                    return 0;
13772                }
13773            });
13774        }
13775
13776        for (int i=0; i<items.size(); i++) {
13777            MemItem mi = items.get(i);
13778            if (!isCompact) {
13779                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13780            } else if (mi.isProc) {
13781                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13782                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13783                pw.println(mi.hasActivities ? ",a" : ",e");
13784            } else {
13785                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13786                pw.println(mi.pss);
13787            }
13788            if (mi.subitems != null) {
13789                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13790                        true, isCompact);
13791            }
13792        }
13793    }
13794
13795    // These are in KB.
13796    static final long[] DUMP_MEM_BUCKETS = new long[] {
13797        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13798        120*1024, 160*1024, 200*1024,
13799        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13800        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13801    };
13802
13803    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13804            boolean stackLike) {
13805        int start = label.lastIndexOf('.');
13806        if (start >= 0) start++;
13807        else start = 0;
13808        int end = label.length();
13809        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13810            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13811                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13812                out.append(bucket);
13813                out.append(stackLike ? "MB." : "MB ");
13814                out.append(label, start, end);
13815                return;
13816            }
13817        }
13818        out.append(memKB/1024);
13819        out.append(stackLike ? "MB." : "MB ");
13820        out.append(label, start, end);
13821    }
13822
13823    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13824            ProcessList.NATIVE_ADJ,
13825            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13826            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13827            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13828            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13829            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13830            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13831    };
13832    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13833            "Native",
13834            "System", "Persistent", "Persistent Service", "Foreground",
13835            "Visible", "Perceptible",
13836            "Heavy Weight", "Backup",
13837            "A Services", "Home",
13838            "Previous", "B Services", "Cached"
13839    };
13840    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13841            "native",
13842            "sys", "pers", "persvc", "fore",
13843            "vis", "percept",
13844            "heavy", "backup",
13845            "servicea", "home",
13846            "prev", "serviceb", "cached"
13847    };
13848
13849    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13850            long realtime, boolean isCheckinRequest, boolean isCompact) {
13851        if (isCheckinRequest || isCompact) {
13852            // short checkin version
13853            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13854        } else {
13855            pw.println("Applications Memory Usage (kB):");
13856            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13857        }
13858    }
13859
13860    private static final int KSM_SHARED = 0;
13861    private static final int KSM_SHARING = 1;
13862    private static final int KSM_UNSHARED = 2;
13863    private static final int KSM_VOLATILE = 3;
13864
13865    private final long[] getKsmInfo() {
13866        long[] longOut = new long[4];
13867        final int[] SINGLE_LONG_FORMAT = new int[] {
13868            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13869        };
13870        long[] longTmp = new long[1];
13871        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13872                SINGLE_LONG_FORMAT, null, longTmp, null);
13873        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13874        longTmp[0] = 0;
13875        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13876                SINGLE_LONG_FORMAT, null, longTmp, null);
13877        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13878        longTmp[0] = 0;
13879        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13880                SINGLE_LONG_FORMAT, null, longTmp, null);
13881        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13882        longTmp[0] = 0;
13883        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13884                SINGLE_LONG_FORMAT, null, longTmp, null);
13885        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13886        return longOut;
13887    }
13888
13889    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13890            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13891        boolean dumpDetails = false;
13892        boolean dumpFullDetails = false;
13893        boolean dumpDalvik = false;
13894        boolean oomOnly = false;
13895        boolean isCompact = false;
13896        boolean localOnly = false;
13897        boolean packages = false;
13898
13899        int opti = 0;
13900        while (opti < args.length) {
13901            String opt = args[opti];
13902            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13903                break;
13904            }
13905            opti++;
13906            if ("-a".equals(opt)) {
13907                dumpDetails = true;
13908                dumpFullDetails = true;
13909                dumpDalvik = true;
13910            } else if ("-d".equals(opt)) {
13911                dumpDalvik = true;
13912            } else if ("-c".equals(opt)) {
13913                isCompact = true;
13914            } else if ("--oom".equals(opt)) {
13915                oomOnly = true;
13916            } else if ("--local".equals(opt)) {
13917                localOnly = true;
13918            } else if ("--package".equals(opt)) {
13919                packages = true;
13920            } else if ("-h".equals(opt)) {
13921                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13922                pw.println("  -a: include all available information for each process.");
13923                pw.println("  -d: include dalvik details when dumping process details.");
13924                pw.println("  -c: dump in a compact machine-parseable representation.");
13925                pw.println("  --oom: only show processes organized by oom adj.");
13926                pw.println("  --local: only collect details locally, don't call process.");
13927                pw.println("  --package: interpret process arg as package, dumping all");
13928                pw.println("             processes that have loaded that package.");
13929                pw.println("If [process] is specified it can be the name or ");
13930                pw.println("pid of a specific process to dump.");
13931                return;
13932            } else {
13933                pw.println("Unknown argument: " + opt + "; use -h for help");
13934            }
13935        }
13936
13937        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13938        long uptime = SystemClock.uptimeMillis();
13939        long realtime = SystemClock.elapsedRealtime();
13940        final long[] tmpLong = new long[1];
13941
13942        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13943        if (procs == null) {
13944            // No Java processes.  Maybe they want to print a native process.
13945            if (args != null && args.length > opti
13946                    && args[opti].charAt(0) != '-') {
13947                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13948                        = new ArrayList<ProcessCpuTracker.Stats>();
13949                updateCpuStatsNow();
13950                int findPid = -1;
13951                try {
13952                    findPid = Integer.parseInt(args[opti]);
13953                } catch (NumberFormatException e) {
13954                }
13955                synchronized (mProcessCpuTracker) {
13956                    final int N = mProcessCpuTracker.countStats();
13957                    for (int i=0; i<N; i++) {
13958                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13959                        if (st.pid == findPid || (st.baseName != null
13960                                && st.baseName.equals(args[opti]))) {
13961                            nativeProcs.add(st);
13962                        }
13963                    }
13964                }
13965                if (nativeProcs.size() > 0) {
13966                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13967                            isCompact);
13968                    Debug.MemoryInfo mi = null;
13969                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13970                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13971                        final int pid = r.pid;
13972                        if (!isCheckinRequest && dumpDetails) {
13973                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13974                        }
13975                        if (mi == null) {
13976                            mi = new Debug.MemoryInfo();
13977                        }
13978                        if (dumpDetails || (!brief && !oomOnly)) {
13979                            Debug.getMemoryInfo(pid, mi);
13980                        } else {
13981                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13982                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13983                        }
13984                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13985                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13986                        if (isCheckinRequest) {
13987                            pw.println();
13988                        }
13989                    }
13990                    return;
13991                }
13992            }
13993            pw.println("No process found for: " + args[opti]);
13994            return;
13995        }
13996
13997        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13998            dumpDetails = true;
13999        }
14000
14001        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14002
14003        String[] innerArgs = new String[args.length-opti];
14004        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14005
14006        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14007        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14008        long nativePss = 0;
14009        long dalvikPss = 0;
14010        long otherPss = 0;
14011        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14012
14013        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14014        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14015                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14016
14017        long totalPss = 0;
14018        long cachedPss = 0;
14019
14020        Debug.MemoryInfo mi = null;
14021        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14022            final ProcessRecord r = procs.get(i);
14023            final IApplicationThread thread;
14024            final int pid;
14025            final int oomAdj;
14026            final boolean hasActivities;
14027            synchronized (this) {
14028                thread = r.thread;
14029                pid = r.pid;
14030                oomAdj = r.getSetAdjWithServices();
14031                hasActivities = r.activities.size() > 0;
14032            }
14033            if (thread != null) {
14034                if (!isCheckinRequest && dumpDetails) {
14035                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14036                }
14037                if (mi == null) {
14038                    mi = new Debug.MemoryInfo();
14039                }
14040                if (dumpDetails || (!brief && !oomOnly)) {
14041                    Debug.getMemoryInfo(pid, mi);
14042                } else {
14043                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14044                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14045                }
14046                if (dumpDetails) {
14047                    if (localOnly) {
14048                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14049                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14050                        if (isCheckinRequest) {
14051                            pw.println();
14052                        }
14053                    } else {
14054                        try {
14055                            pw.flush();
14056                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14057                                    dumpDalvik, innerArgs);
14058                        } catch (RemoteException e) {
14059                            if (!isCheckinRequest) {
14060                                pw.println("Got RemoteException!");
14061                                pw.flush();
14062                            }
14063                        }
14064                    }
14065                }
14066
14067                final long myTotalPss = mi.getTotalPss();
14068                final long myTotalUss = mi.getTotalUss();
14069
14070                synchronized (this) {
14071                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14072                        // Record this for posterity if the process has been stable.
14073                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14074                    }
14075                }
14076
14077                if (!isCheckinRequest && mi != null) {
14078                    totalPss += myTotalPss;
14079                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14080                            (hasActivities ? " / activities)" : ")"),
14081                            r.processName, myTotalPss, pid, hasActivities);
14082                    procMems.add(pssItem);
14083                    procMemsMap.put(pid, pssItem);
14084
14085                    nativePss += mi.nativePss;
14086                    dalvikPss += mi.dalvikPss;
14087                    otherPss += mi.otherPss;
14088                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14089                        long mem = mi.getOtherPss(j);
14090                        miscPss[j] += mem;
14091                        otherPss -= mem;
14092                    }
14093
14094                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14095                        cachedPss += myTotalPss;
14096                    }
14097
14098                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14099                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14100                                || oomIndex == (oomPss.length-1)) {
14101                            oomPss[oomIndex] += myTotalPss;
14102                            if (oomProcs[oomIndex] == null) {
14103                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14104                            }
14105                            oomProcs[oomIndex].add(pssItem);
14106                            break;
14107                        }
14108                    }
14109                }
14110            }
14111        }
14112
14113        long nativeProcTotalPss = 0;
14114
14115        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14116            // If we are showing aggregations, also look for native processes to
14117            // include so that our aggregations are more accurate.
14118            updateCpuStatsNow();
14119            synchronized (mProcessCpuTracker) {
14120                final int N = mProcessCpuTracker.countStats();
14121                for (int i=0; i<N; i++) {
14122                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14123                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14124                        if (mi == null) {
14125                            mi = new Debug.MemoryInfo();
14126                        }
14127                        if (!brief && !oomOnly) {
14128                            Debug.getMemoryInfo(st.pid, mi);
14129                        } else {
14130                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14131                            mi.nativePrivateDirty = (int)tmpLong[0];
14132                        }
14133
14134                        final long myTotalPss = mi.getTotalPss();
14135                        totalPss += myTotalPss;
14136                        nativeProcTotalPss += myTotalPss;
14137
14138                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14139                                st.name, myTotalPss, st.pid, false);
14140                        procMems.add(pssItem);
14141
14142                        nativePss += mi.nativePss;
14143                        dalvikPss += mi.dalvikPss;
14144                        otherPss += mi.otherPss;
14145                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14146                            long mem = mi.getOtherPss(j);
14147                            miscPss[j] += mem;
14148                            otherPss -= mem;
14149                        }
14150                        oomPss[0] += myTotalPss;
14151                        if (oomProcs[0] == null) {
14152                            oomProcs[0] = new ArrayList<MemItem>();
14153                        }
14154                        oomProcs[0].add(pssItem);
14155                    }
14156                }
14157            }
14158
14159            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14160
14161            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14162            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14163            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14164            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14165                String label = Debug.MemoryInfo.getOtherLabel(j);
14166                catMems.add(new MemItem(label, label, miscPss[j], j));
14167            }
14168
14169            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14170            for (int j=0; j<oomPss.length; j++) {
14171                if (oomPss[j] != 0) {
14172                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14173                            : DUMP_MEM_OOM_LABEL[j];
14174                    MemItem item = new MemItem(label, label, oomPss[j],
14175                            DUMP_MEM_OOM_ADJ[j]);
14176                    item.subitems = oomProcs[j];
14177                    oomMems.add(item);
14178                }
14179            }
14180
14181            if (!brief && !oomOnly && !isCompact) {
14182                pw.println();
14183                pw.println("Total PSS by process:");
14184                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14185                pw.println();
14186            }
14187            if (!isCompact) {
14188                pw.println("Total PSS by OOM adjustment:");
14189            }
14190            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14191            if (!brief && !oomOnly) {
14192                PrintWriter out = categoryPw != null ? categoryPw : pw;
14193                if (!isCompact) {
14194                    out.println();
14195                    out.println("Total PSS by category:");
14196                }
14197                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14198            }
14199            if (!isCompact) {
14200                pw.println();
14201            }
14202            MemInfoReader memInfo = new MemInfoReader();
14203            memInfo.readMemInfo();
14204            if (nativeProcTotalPss > 0) {
14205                synchronized (this) {
14206                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14207                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14208                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14209                }
14210            }
14211            if (!brief) {
14212                if (!isCompact) {
14213                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14214                    pw.print(" kB (status ");
14215                    switch (mLastMemoryLevel) {
14216                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14217                            pw.println("normal)");
14218                            break;
14219                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14220                            pw.println("moderate)");
14221                            break;
14222                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14223                            pw.println("low)");
14224                            break;
14225                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14226                            pw.println("critical)");
14227                            break;
14228                        default:
14229                            pw.print(mLastMemoryLevel);
14230                            pw.println(")");
14231                            break;
14232                    }
14233                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14234                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14235                            pw.print(cachedPss); pw.print(" cached pss + ");
14236                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14237                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14238                } else {
14239                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14240                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14241                            + memInfo.getFreeSizeKb()); pw.print(",");
14242                    pw.println(totalPss - cachedPss);
14243                }
14244            }
14245            if (!isCompact) {
14246                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14247                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14248                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14249                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14250                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14251                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14252                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14253            }
14254            if (!brief) {
14255                if (memInfo.getZramTotalSizeKb() != 0) {
14256                    if (!isCompact) {
14257                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14258                                pw.print(" kB physical used for ");
14259                                pw.print(memInfo.getSwapTotalSizeKb()
14260                                        - memInfo.getSwapFreeSizeKb());
14261                                pw.print(" kB in swap (");
14262                                pw.print(memInfo.getSwapTotalSizeKb());
14263                                pw.println(" kB total swap)");
14264                    } else {
14265                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14266                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14267                                pw.println(memInfo.getSwapFreeSizeKb());
14268                    }
14269                }
14270                final long[] ksm = getKsmInfo();
14271                if (!isCompact) {
14272                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14273                            || ksm[KSM_VOLATILE] != 0) {
14274                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14275                                pw.print(" kB saved from shared ");
14276                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14277                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14278                                pw.print(" kB unshared; ");
14279                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14280                    }
14281                    pw.print("   Tuning: ");
14282                    pw.print(ActivityManager.staticGetMemoryClass());
14283                    pw.print(" (large ");
14284                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14285                    pw.print("), oom ");
14286                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14287                    pw.print(" kB");
14288                    pw.print(", restore limit ");
14289                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14290                    pw.print(" kB");
14291                    if (ActivityManager.isLowRamDeviceStatic()) {
14292                        pw.print(" (low-ram)");
14293                    }
14294                    if (ActivityManager.isHighEndGfx()) {
14295                        pw.print(" (high-end-gfx)");
14296                    }
14297                    pw.println();
14298                } else {
14299                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14300                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14301                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14302                    pw.print("tuning,");
14303                    pw.print(ActivityManager.staticGetMemoryClass());
14304                    pw.print(',');
14305                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14306                    pw.print(',');
14307                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14308                    if (ActivityManager.isLowRamDeviceStatic()) {
14309                        pw.print(",low-ram");
14310                    }
14311                    if (ActivityManager.isHighEndGfx()) {
14312                        pw.print(",high-end-gfx");
14313                    }
14314                    pw.println();
14315                }
14316            }
14317        }
14318    }
14319
14320    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14321            String name) {
14322        sb.append("  ");
14323        sb.append(ProcessList.makeOomAdjString(oomAdj));
14324        sb.append(' ');
14325        sb.append(ProcessList.makeProcStateString(procState));
14326        sb.append(' ');
14327        ProcessList.appendRamKb(sb, pss);
14328        sb.append(" kB: ");
14329        sb.append(name);
14330    }
14331
14332    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14333        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14334        sb.append(" (");
14335        sb.append(mi.pid);
14336        sb.append(") ");
14337        sb.append(mi.adjType);
14338        sb.append('\n');
14339        if (mi.adjReason != null) {
14340            sb.append("                      ");
14341            sb.append(mi.adjReason);
14342            sb.append('\n');
14343        }
14344    }
14345
14346    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14347        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14348        for (int i=0, N=memInfos.size(); i<N; i++) {
14349            ProcessMemInfo mi = memInfos.get(i);
14350            infoMap.put(mi.pid, mi);
14351        }
14352        updateCpuStatsNow();
14353        synchronized (mProcessCpuTracker) {
14354            final int N = mProcessCpuTracker.countStats();
14355            for (int i=0; i<N; i++) {
14356                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14357                if (st.vsize > 0) {
14358                    long pss = Debug.getPss(st.pid, null);
14359                    if (pss > 0) {
14360                        if (infoMap.indexOfKey(st.pid) < 0) {
14361                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14362                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14363                            mi.pss = pss;
14364                            memInfos.add(mi);
14365                        }
14366                    }
14367                }
14368            }
14369        }
14370
14371        long totalPss = 0;
14372        for (int i=0, N=memInfos.size(); i<N; i++) {
14373            ProcessMemInfo mi = memInfos.get(i);
14374            if (mi.pss == 0) {
14375                mi.pss = Debug.getPss(mi.pid, null);
14376            }
14377            totalPss += mi.pss;
14378        }
14379        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14380            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14381                if (lhs.oomAdj != rhs.oomAdj) {
14382                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14383                }
14384                if (lhs.pss != rhs.pss) {
14385                    return lhs.pss < rhs.pss ? 1 : -1;
14386                }
14387                return 0;
14388            }
14389        });
14390
14391        StringBuilder tag = new StringBuilder(128);
14392        StringBuilder stack = new StringBuilder(128);
14393        tag.append("Low on memory -- ");
14394        appendMemBucket(tag, totalPss, "total", false);
14395        appendMemBucket(stack, totalPss, "total", true);
14396
14397        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14398        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14399        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14400
14401        boolean firstLine = true;
14402        int lastOomAdj = Integer.MIN_VALUE;
14403        long extraNativeRam = 0;
14404        long cachedPss = 0;
14405        for (int i=0, N=memInfos.size(); i<N; i++) {
14406            ProcessMemInfo mi = memInfos.get(i);
14407
14408            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14409                cachedPss += mi.pss;
14410            }
14411
14412            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14413                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14414                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14415                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14416                if (lastOomAdj != mi.oomAdj) {
14417                    lastOomAdj = mi.oomAdj;
14418                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14419                        tag.append(" / ");
14420                    }
14421                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14422                        if (firstLine) {
14423                            stack.append(":");
14424                            firstLine = false;
14425                        }
14426                        stack.append("\n\t at ");
14427                    } else {
14428                        stack.append("$");
14429                    }
14430                } else {
14431                    tag.append(" ");
14432                    stack.append("$");
14433                }
14434                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14435                    appendMemBucket(tag, mi.pss, mi.name, false);
14436                }
14437                appendMemBucket(stack, mi.pss, mi.name, true);
14438                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14439                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14440                    stack.append("(");
14441                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14442                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14443                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14444                            stack.append(":");
14445                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14446                        }
14447                    }
14448                    stack.append(")");
14449                }
14450            }
14451
14452            appendMemInfo(fullNativeBuilder, mi);
14453            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14454                // The short form only has native processes that are >= 1MB.
14455                if (mi.pss >= 1000) {
14456                    appendMemInfo(shortNativeBuilder, mi);
14457                } else {
14458                    extraNativeRam += mi.pss;
14459                }
14460            } else {
14461                // Short form has all other details, but if we have collected RAM
14462                // from smaller native processes let's dump a summary of that.
14463                if (extraNativeRam > 0) {
14464                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14465                            -1, extraNativeRam, "(Other native)");
14466                    shortNativeBuilder.append('\n');
14467                    extraNativeRam = 0;
14468                }
14469                appendMemInfo(fullJavaBuilder, mi);
14470            }
14471        }
14472
14473        fullJavaBuilder.append("           ");
14474        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14475        fullJavaBuilder.append(" kB: TOTAL\n");
14476
14477        MemInfoReader memInfo = new MemInfoReader();
14478        memInfo.readMemInfo();
14479        final long[] infos = memInfo.getRawInfo();
14480
14481        StringBuilder memInfoBuilder = new StringBuilder(1024);
14482        Debug.getMemInfo(infos);
14483        memInfoBuilder.append("  MemInfo: ");
14484        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14485        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14486        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14487        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14488        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14489        memInfoBuilder.append("           ");
14490        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14491        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14492        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14493        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14494        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14495            memInfoBuilder.append("  ZRAM: ");
14496            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14497            memInfoBuilder.append(" kB RAM, ");
14498            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14499            memInfoBuilder.append(" kB swap total, ");
14500            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14501            memInfoBuilder.append(" kB swap free\n");
14502        }
14503        final long[] ksm = getKsmInfo();
14504        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14505                || ksm[KSM_VOLATILE] != 0) {
14506            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14507            memInfoBuilder.append(" kB saved from shared ");
14508            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14509            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14510            memInfoBuilder.append(" kB unshared; ");
14511            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14512        }
14513        memInfoBuilder.append("  Free RAM: ");
14514        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14515                + memInfo.getFreeSizeKb());
14516        memInfoBuilder.append(" kB\n");
14517        memInfoBuilder.append("  Used RAM: ");
14518        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14519        memInfoBuilder.append(" kB\n");
14520        memInfoBuilder.append("  Lost RAM: ");
14521        memInfoBuilder.append(memInfo.getTotalSizeKb()
14522                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14523                - memInfo.getKernelUsedSizeKb());
14524        memInfoBuilder.append(" kB\n");
14525        Slog.i(TAG, "Low on memory:");
14526        Slog.i(TAG, shortNativeBuilder.toString());
14527        Slog.i(TAG, fullJavaBuilder.toString());
14528        Slog.i(TAG, memInfoBuilder.toString());
14529
14530        StringBuilder dropBuilder = new StringBuilder(1024);
14531        /*
14532        StringWriter oomSw = new StringWriter();
14533        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14534        StringWriter catSw = new StringWriter();
14535        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14536        String[] emptyArgs = new String[] { };
14537        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14538        oomPw.flush();
14539        String oomString = oomSw.toString();
14540        */
14541        dropBuilder.append("Low on memory:");
14542        dropBuilder.append(stack);
14543        dropBuilder.append('\n');
14544        dropBuilder.append(fullNativeBuilder);
14545        dropBuilder.append(fullJavaBuilder);
14546        dropBuilder.append('\n');
14547        dropBuilder.append(memInfoBuilder);
14548        dropBuilder.append('\n');
14549        /*
14550        dropBuilder.append(oomString);
14551        dropBuilder.append('\n');
14552        */
14553        StringWriter catSw = new StringWriter();
14554        synchronized (ActivityManagerService.this) {
14555            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14556            String[] emptyArgs = new String[] { };
14557            catPw.println();
14558            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14559            catPw.println();
14560            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14561                    false, false, null);
14562            catPw.println();
14563            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14564            catPw.flush();
14565        }
14566        dropBuilder.append(catSw.toString());
14567        addErrorToDropBox("lowmem", null, "system_server", null,
14568                null, tag.toString(), dropBuilder.toString(), null, null);
14569        //Slog.i(TAG, "Sent to dropbox:");
14570        //Slog.i(TAG, dropBuilder.toString());
14571        synchronized (ActivityManagerService.this) {
14572            long now = SystemClock.uptimeMillis();
14573            if (mLastMemUsageReportTime < now) {
14574                mLastMemUsageReportTime = now;
14575            }
14576        }
14577    }
14578
14579    /**
14580     * Searches array of arguments for the specified string
14581     * @param args array of argument strings
14582     * @param value value to search for
14583     * @return true if the value is contained in the array
14584     */
14585    private static boolean scanArgs(String[] args, String value) {
14586        if (args != null) {
14587            for (String arg : args) {
14588                if (value.equals(arg)) {
14589                    return true;
14590                }
14591            }
14592        }
14593        return false;
14594    }
14595
14596    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14597            ContentProviderRecord cpr, boolean always) {
14598        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14599
14600        if (!inLaunching || always) {
14601            synchronized (cpr) {
14602                cpr.launchingApp = null;
14603                cpr.notifyAll();
14604            }
14605            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14606            String names[] = cpr.info.authority.split(";");
14607            for (int j = 0; j < names.length; j++) {
14608                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14609            }
14610        }
14611
14612        for (int i=0; i<cpr.connections.size(); i++) {
14613            ContentProviderConnection conn = cpr.connections.get(i);
14614            if (conn.waiting) {
14615                // If this connection is waiting for the provider, then we don't
14616                // need to mess with its process unless we are always removing
14617                // or for some reason the provider is not currently launching.
14618                if (inLaunching && !always) {
14619                    continue;
14620                }
14621            }
14622            ProcessRecord capp = conn.client;
14623            conn.dead = true;
14624            if (conn.stableCount > 0) {
14625                if (!capp.persistent && capp.thread != null
14626                        && capp.pid != 0
14627                        && capp.pid != MY_PID) {
14628                    capp.kill("depends on provider "
14629                            + cpr.name.flattenToShortString()
14630                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14631                }
14632            } else if (capp.thread != null && conn.provider.provider != null) {
14633                try {
14634                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14635                } catch (RemoteException e) {
14636                }
14637                // In the protocol here, we don't expect the client to correctly
14638                // clean up this connection, we'll just remove it.
14639                cpr.connections.remove(i);
14640                conn.client.conProviders.remove(conn);
14641            }
14642        }
14643
14644        if (inLaunching && always) {
14645            mLaunchingProviders.remove(cpr);
14646        }
14647        return inLaunching;
14648    }
14649
14650    /**
14651     * Main code for cleaning up a process when it has gone away.  This is
14652     * called both as a result of the process dying, or directly when stopping
14653     * a process when running in single process mode.
14654     *
14655     * @return Returns true if the given process has been restarted, so the
14656     * app that was passed in must remain on the process lists.
14657     */
14658    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14659            boolean restarting, boolean allowRestart, int index) {
14660        if (index >= 0) {
14661            removeLruProcessLocked(app);
14662            ProcessList.remove(app.pid);
14663        }
14664
14665        mProcessesToGc.remove(app);
14666        mPendingPssProcesses.remove(app);
14667
14668        // Dismiss any open dialogs.
14669        if (app.crashDialog != null && !app.forceCrashReport) {
14670            app.crashDialog.dismiss();
14671            app.crashDialog = null;
14672        }
14673        if (app.anrDialog != null) {
14674            app.anrDialog.dismiss();
14675            app.anrDialog = null;
14676        }
14677        if (app.waitDialog != null) {
14678            app.waitDialog.dismiss();
14679            app.waitDialog = null;
14680        }
14681
14682        app.crashing = false;
14683        app.notResponding = false;
14684
14685        app.resetPackageList(mProcessStats);
14686        app.unlinkDeathRecipient();
14687        app.makeInactive(mProcessStats);
14688        app.waitingToKill = null;
14689        app.forcingToForeground = null;
14690        updateProcessForegroundLocked(app, false, false);
14691        app.foregroundActivities = false;
14692        app.hasShownUi = false;
14693        app.treatLikeActivity = false;
14694        app.hasAboveClient = false;
14695        app.hasClientActivities = false;
14696
14697        mServices.killServicesLocked(app, allowRestart);
14698
14699        boolean restart = false;
14700
14701        // Remove published content providers.
14702        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14703            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14704            final boolean always = app.bad || !allowRestart;
14705            if (removeDyingProviderLocked(app, cpr, always) || always) {
14706                // We left the provider in the launching list, need to
14707                // restart it.
14708                restart = true;
14709            }
14710
14711            cpr.provider = null;
14712            cpr.proc = null;
14713        }
14714        app.pubProviders.clear();
14715
14716        // Take care of any launching providers waiting for this process.
14717        if (checkAppInLaunchingProvidersLocked(app, false)) {
14718            restart = true;
14719        }
14720
14721        // Unregister from connected content providers.
14722        if (!app.conProviders.isEmpty()) {
14723            for (int i=0; i<app.conProviders.size(); i++) {
14724                ContentProviderConnection conn = app.conProviders.get(i);
14725                conn.provider.connections.remove(conn);
14726            }
14727            app.conProviders.clear();
14728        }
14729
14730        // At this point there may be remaining entries in mLaunchingProviders
14731        // where we were the only one waiting, so they are no longer of use.
14732        // Look for these and clean up if found.
14733        // XXX Commented out for now.  Trying to figure out a way to reproduce
14734        // the actual situation to identify what is actually going on.
14735        if (false) {
14736            for (int i=0; i<mLaunchingProviders.size(); i++) {
14737                ContentProviderRecord cpr = (ContentProviderRecord)
14738                        mLaunchingProviders.get(i);
14739                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14740                    synchronized (cpr) {
14741                        cpr.launchingApp = null;
14742                        cpr.notifyAll();
14743                    }
14744                }
14745            }
14746        }
14747
14748        skipCurrentReceiverLocked(app);
14749
14750        // Unregister any receivers.
14751        for (int i=app.receivers.size()-1; i>=0; i--) {
14752            removeReceiverLocked(app.receivers.valueAt(i));
14753        }
14754        app.receivers.clear();
14755
14756        // If the app is undergoing backup, tell the backup manager about it
14757        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14758            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14759                    + mBackupTarget.appInfo + " died during backup");
14760            try {
14761                IBackupManager bm = IBackupManager.Stub.asInterface(
14762                        ServiceManager.getService(Context.BACKUP_SERVICE));
14763                bm.agentDisconnected(app.info.packageName);
14764            } catch (RemoteException e) {
14765                // can't happen; backup manager is local
14766            }
14767        }
14768
14769        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14770            ProcessChangeItem item = mPendingProcessChanges.get(i);
14771            if (item.pid == app.pid) {
14772                mPendingProcessChanges.remove(i);
14773                mAvailProcessChanges.add(item);
14774            }
14775        }
14776        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14777
14778        // If the caller is restarting this app, then leave it in its
14779        // current lists and let the caller take care of it.
14780        if (restarting) {
14781            return false;
14782        }
14783
14784        if (!app.persistent || app.isolated) {
14785            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14786                    "Removing non-persistent process during cleanup: " + app);
14787            mProcessNames.remove(app.processName, app.uid);
14788            mIsolatedProcesses.remove(app.uid);
14789            if (mHeavyWeightProcess == app) {
14790                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14791                        mHeavyWeightProcess.userId, 0));
14792                mHeavyWeightProcess = null;
14793            }
14794        } else if (!app.removed) {
14795            // This app is persistent, so we need to keep its record around.
14796            // If it is not already on the pending app list, add it there
14797            // and start a new process for it.
14798            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14799                mPersistentStartingProcesses.add(app);
14800                restart = true;
14801            }
14802        }
14803        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14804                "Clean-up removing on hold: " + app);
14805        mProcessesOnHold.remove(app);
14806
14807        if (app == mHomeProcess) {
14808            mHomeProcess = null;
14809        }
14810        if (app == mPreviousProcess) {
14811            mPreviousProcess = null;
14812        }
14813
14814        if (restart && !app.isolated) {
14815            // We have components that still need to be running in the
14816            // process, so re-launch it.
14817            if (index < 0) {
14818                ProcessList.remove(app.pid);
14819            }
14820            mProcessNames.put(app.processName, app.uid, app);
14821            startProcessLocked(app, "restart", app.processName);
14822            return true;
14823        } else if (app.pid > 0 && app.pid != MY_PID) {
14824            // Goodbye!
14825            boolean removed;
14826            synchronized (mPidsSelfLocked) {
14827                mPidsSelfLocked.remove(app.pid);
14828                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14829            }
14830            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14831            if (app.isolated) {
14832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14833            }
14834            app.setPid(0);
14835        }
14836        return false;
14837    }
14838
14839    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14840        // Look through the content providers we are waiting to have launched,
14841        // and if any run in this process then either schedule a restart of
14842        // the process or kill the client waiting for it if this process has
14843        // gone bad.
14844        int NL = mLaunchingProviders.size();
14845        boolean restart = false;
14846        for (int i=0; i<NL; i++) {
14847            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14848            if (cpr.launchingApp == app) {
14849                if (!alwaysBad && !app.bad) {
14850                    restart = true;
14851                } else {
14852                    removeDyingProviderLocked(app, cpr, true);
14853                    // cpr should have been removed from mLaunchingProviders
14854                    NL = mLaunchingProviders.size();
14855                    i--;
14856                }
14857            }
14858        }
14859        return restart;
14860    }
14861
14862    // =========================================================
14863    // SERVICES
14864    // =========================================================
14865
14866    @Override
14867    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14868            int flags) {
14869        enforceNotIsolatedCaller("getServices");
14870        synchronized (this) {
14871            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14872        }
14873    }
14874
14875    @Override
14876    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14877        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14878        synchronized (this) {
14879            return mServices.getRunningServiceControlPanelLocked(name);
14880        }
14881    }
14882
14883    @Override
14884    public ComponentName startService(IApplicationThread caller, Intent service,
14885            String resolvedType, int userId) {
14886        enforceNotIsolatedCaller("startService");
14887        // Refuse possible leaked file descriptors
14888        if (service != null && service.hasFileDescriptors() == true) {
14889            throw new IllegalArgumentException("File descriptors passed in Intent");
14890        }
14891
14892        if (DEBUG_SERVICE)
14893            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14894        synchronized(this) {
14895            final int callingPid = Binder.getCallingPid();
14896            final int callingUid = Binder.getCallingUid();
14897            final long origId = Binder.clearCallingIdentity();
14898            ComponentName res = mServices.startServiceLocked(caller, service,
14899                    resolvedType, callingPid, callingUid, userId);
14900            Binder.restoreCallingIdentity(origId);
14901            return res;
14902        }
14903    }
14904
14905    ComponentName startServiceInPackage(int uid,
14906            Intent service, String resolvedType, int userId) {
14907        synchronized(this) {
14908            if (DEBUG_SERVICE)
14909                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14910            final long origId = Binder.clearCallingIdentity();
14911            ComponentName res = mServices.startServiceLocked(null, service,
14912                    resolvedType, -1, uid, userId);
14913            Binder.restoreCallingIdentity(origId);
14914            return res;
14915        }
14916    }
14917
14918    @Override
14919    public int stopService(IApplicationThread caller, Intent service,
14920            String resolvedType, int userId) {
14921        enforceNotIsolatedCaller("stopService");
14922        // Refuse possible leaked file descriptors
14923        if (service != null && service.hasFileDescriptors() == true) {
14924            throw new IllegalArgumentException("File descriptors passed in Intent");
14925        }
14926
14927        synchronized(this) {
14928            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14929        }
14930    }
14931
14932    @Override
14933    public IBinder peekService(Intent service, String resolvedType) {
14934        enforceNotIsolatedCaller("peekService");
14935        // Refuse possible leaked file descriptors
14936        if (service != null && service.hasFileDescriptors() == true) {
14937            throw new IllegalArgumentException("File descriptors passed in Intent");
14938        }
14939        synchronized(this) {
14940            return mServices.peekServiceLocked(service, resolvedType);
14941        }
14942    }
14943
14944    @Override
14945    public boolean stopServiceToken(ComponentName className, IBinder token,
14946            int startId) {
14947        synchronized(this) {
14948            return mServices.stopServiceTokenLocked(className, token, startId);
14949        }
14950    }
14951
14952    @Override
14953    public void setServiceForeground(ComponentName className, IBinder token,
14954            int id, Notification notification, boolean removeNotification) {
14955        synchronized(this) {
14956            mServices.setServiceForegroundLocked(className, token, id, notification,
14957                    removeNotification);
14958        }
14959    }
14960
14961    @Override
14962    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14963            boolean requireFull, String name, String callerPackage) {
14964        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14965                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14966    }
14967
14968    int unsafeConvertIncomingUser(int userId) {
14969        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14970                ? mCurrentUserId : userId;
14971    }
14972
14973    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14974            int allowMode, String name, String callerPackage) {
14975        final int callingUserId = UserHandle.getUserId(callingUid);
14976        if (callingUserId == userId) {
14977            return userId;
14978        }
14979
14980        // Note that we may be accessing mCurrentUserId outside of a lock...
14981        // shouldn't be a big deal, if this is being called outside
14982        // of a locked context there is intrinsically a race with
14983        // the value the caller will receive and someone else changing it.
14984        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14985        // we will switch to the calling user if access to the current user fails.
14986        int targetUserId = unsafeConvertIncomingUser(userId);
14987
14988        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14989            final boolean allow;
14990            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14991                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14992                // If the caller has this permission, they always pass go.  And collect $200.
14993                allow = true;
14994            } else if (allowMode == ALLOW_FULL_ONLY) {
14995                // We require full access, sucks to be you.
14996                allow = false;
14997            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14998                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14999                // If the caller does not have either permission, they are always doomed.
15000                allow = false;
15001            } else if (allowMode == ALLOW_NON_FULL) {
15002                // We are blanket allowing non-full access, you lucky caller!
15003                allow = true;
15004            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15005                // We may or may not allow this depending on whether the two users are
15006                // in the same profile.
15007                synchronized (mUserProfileGroupIdsSelfLocked) {
15008                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15009                            UserInfo.NO_PROFILE_GROUP_ID);
15010                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15011                            UserInfo.NO_PROFILE_GROUP_ID);
15012                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15013                            && callingProfile == targetProfile;
15014                }
15015            } else {
15016                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15017            }
15018            if (!allow) {
15019                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15020                    // In this case, they would like to just execute as their
15021                    // owner user instead of failing.
15022                    targetUserId = callingUserId;
15023                } else {
15024                    StringBuilder builder = new StringBuilder(128);
15025                    builder.append("Permission Denial: ");
15026                    builder.append(name);
15027                    if (callerPackage != null) {
15028                        builder.append(" from ");
15029                        builder.append(callerPackage);
15030                    }
15031                    builder.append(" asks to run as user ");
15032                    builder.append(userId);
15033                    builder.append(" but is calling from user ");
15034                    builder.append(UserHandle.getUserId(callingUid));
15035                    builder.append("; this requires ");
15036                    builder.append(INTERACT_ACROSS_USERS_FULL);
15037                    if (allowMode != ALLOW_FULL_ONLY) {
15038                        builder.append(" or ");
15039                        builder.append(INTERACT_ACROSS_USERS);
15040                    }
15041                    String msg = builder.toString();
15042                    Slog.w(TAG, msg);
15043                    throw new SecurityException(msg);
15044                }
15045            }
15046        }
15047        if (!allowAll && targetUserId < 0) {
15048            throw new IllegalArgumentException(
15049                    "Call does not support special user #" + targetUserId);
15050        }
15051        // Check shell permission
15052        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15053            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15054                    targetUserId)) {
15055                throw new SecurityException("Shell does not have permission to access user "
15056                        + targetUserId + "\n " + Debug.getCallers(3));
15057            }
15058        }
15059        return targetUserId;
15060    }
15061
15062    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15063            String className, int flags) {
15064        boolean result = false;
15065        // For apps that don't have pre-defined UIDs, check for permission
15066        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15067            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15068                if (ActivityManager.checkUidPermission(
15069                        INTERACT_ACROSS_USERS,
15070                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15071                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15072                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15073                            + " requests FLAG_SINGLE_USER, but app does not hold "
15074                            + INTERACT_ACROSS_USERS;
15075                    Slog.w(TAG, msg);
15076                    throw new SecurityException(msg);
15077                }
15078                // Permission passed
15079                result = true;
15080            }
15081        } else if ("system".equals(componentProcessName)) {
15082            result = true;
15083        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15084            // Phone app and persistent apps are allowed to export singleuser providers.
15085            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15086                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15087        }
15088        if (DEBUG_MU) {
15089            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15090                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15091        }
15092        return result;
15093    }
15094
15095    /**
15096     * Checks to see if the caller is in the same app as the singleton
15097     * component, or the component is in a special app. It allows special apps
15098     * to export singleton components but prevents exporting singleton
15099     * components for regular apps.
15100     */
15101    boolean isValidSingletonCall(int callingUid, int componentUid) {
15102        int componentAppId = UserHandle.getAppId(componentUid);
15103        return UserHandle.isSameApp(callingUid, componentUid)
15104                || componentAppId == Process.SYSTEM_UID
15105                || componentAppId == Process.PHONE_UID
15106                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15107                        == PackageManager.PERMISSION_GRANTED;
15108    }
15109
15110    public int bindService(IApplicationThread caller, IBinder token,
15111            Intent service, String resolvedType,
15112            IServiceConnection connection, int flags, int userId) {
15113        enforceNotIsolatedCaller("bindService");
15114
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        synchronized(this) {
15121            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15122                    connection, flags, userId);
15123        }
15124    }
15125
15126    public boolean unbindService(IServiceConnection connection) {
15127        synchronized (this) {
15128            return mServices.unbindServiceLocked(connection);
15129        }
15130    }
15131
15132    public void publishService(IBinder token, Intent intent, IBinder service) {
15133        // Refuse possible leaked file descriptors
15134        if (intent != null && intent.hasFileDescriptors() == true) {
15135            throw new IllegalArgumentException("File descriptors passed in Intent");
15136        }
15137
15138        synchronized(this) {
15139            if (!(token instanceof ServiceRecord)) {
15140                throw new IllegalArgumentException("Invalid service token");
15141            }
15142            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15143        }
15144    }
15145
15146    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15147        // Refuse possible leaked file descriptors
15148        if (intent != null && intent.hasFileDescriptors() == true) {
15149            throw new IllegalArgumentException("File descriptors passed in Intent");
15150        }
15151
15152        synchronized(this) {
15153            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15154        }
15155    }
15156
15157    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15158        synchronized(this) {
15159            if (!(token instanceof ServiceRecord)) {
15160                throw new IllegalArgumentException("Invalid service token");
15161            }
15162            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15163        }
15164    }
15165
15166    // =========================================================
15167    // BACKUP AND RESTORE
15168    // =========================================================
15169
15170    // Cause the target app to be launched if necessary and its backup agent
15171    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15172    // activity manager to announce its creation.
15173    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15174        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15175        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15176
15177        synchronized(this) {
15178            // !!! TODO: currently no check here that we're already bound
15179            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15180            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15181            synchronized (stats) {
15182                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15183            }
15184
15185            // Backup agent is now in use, its package can't be stopped.
15186            try {
15187                AppGlobals.getPackageManager().setPackageStoppedState(
15188                        app.packageName, false, UserHandle.getUserId(app.uid));
15189            } catch (RemoteException e) {
15190            } catch (IllegalArgumentException e) {
15191                Slog.w(TAG, "Failed trying to unstop package "
15192                        + app.packageName + ": " + e);
15193            }
15194
15195            BackupRecord r = new BackupRecord(ss, app, backupMode);
15196            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15197                    ? new ComponentName(app.packageName, app.backupAgentName)
15198                    : new ComponentName("android", "FullBackupAgent");
15199            // startProcessLocked() returns existing proc's record if it's already running
15200            ProcessRecord proc = startProcessLocked(app.processName, app,
15201                    false, 0, "backup", hostingName, false, false, false);
15202            if (proc == null) {
15203                Slog.e(TAG, "Unable to start backup agent process " + r);
15204                return false;
15205            }
15206
15207            r.app = proc;
15208            mBackupTarget = r;
15209            mBackupAppName = app.packageName;
15210
15211            // Try not to kill the process during backup
15212            updateOomAdjLocked(proc);
15213
15214            // If the process is already attached, schedule the creation of the backup agent now.
15215            // If it is not yet live, this will be done when it attaches to the framework.
15216            if (proc.thread != null) {
15217                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15218                try {
15219                    proc.thread.scheduleCreateBackupAgent(app,
15220                            compatibilityInfoForPackageLocked(app), backupMode);
15221                } catch (RemoteException e) {
15222                    // Will time out on the backup manager side
15223                }
15224            } else {
15225                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15226            }
15227            // Invariants: at this point, the target app process exists and the application
15228            // is either already running or in the process of coming up.  mBackupTarget and
15229            // mBackupAppName describe the app, so that when it binds back to the AM we
15230            // know that it's scheduled for a backup-agent operation.
15231        }
15232
15233        return true;
15234    }
15235
15236    @Override
15237    public void clearPendingBackup() {
15238        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15239        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15240
15241        synchronized (this) {
15242            mBackupTarget = null;
15243            mBackupAppName = null;
15244        }
15245    }
15246
15247    // A backup agent has just come up
15248    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15249        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15250                + " = " + agent);
15251
15252        synchronized(this) {
15253            if (!agentPackageName.equals(mBackupAppName)) {
15254                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15255                return;
15256            }
15257        }
15258
15259        long oldIdent = Binder.clearCallingIdentity();
15260        try {
15261            IBackupManager bm = IBackupManager.Stub.asInterface(
15262                    ServiceManager.getService(Context.BACKUP_SERVICE));
15263            bm.agentConnected(agentPackageName, agent);
15264        } catch (RemoteException e) {
15265            // can't happen; the backup manager service is local
15266        } catch (Exception e) {
15267            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15268            e.printStackTrace();
15269        } finally {
15270            Binder.restoreCallingIdentity(oldIdent);
15271        }
15272    }
15273
15274    // done with this agent
15275    public void unbindBackupAgent(ApplicationInfo appInfo) {
15276        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15277        if (appInfo == null) {
15278            Slog.w(TAG, "unbind backup agent for null app");
15279            return;
15280        }
15281
15282        synchronized(this) {
15283            try {
15284                if (mBackupAppName == null) {
15285                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15286                    return;
15287                }
15288
15289                if (!mBackupAppName.equals(appInfo.packageName)) {
15290                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15291                    return;
15292                }
15293
15294                // Not backing this app up any more; reset its OOM adjustment
15295                final ProcessRecord proc = mBackupTarget.app;
15296                updateOomAdjLocked(proc);
15297
15298                // If the app crashed during backup, 'thread' will be null here
15299                if (proc.thread != null) {
15300                    try {
15301                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15302                                compatibilityInfoForPackageLocked(appInfo));
15303                    } catch (Exception e) {
15304                        Slog.e(TAG, "Exception when unbinding backup agent:");
15305                        e.printStackTrace();
15306                    }
15307                }
15308            } finally {
15309                mBackupTarget = null;
15310                mBackupAppName = null;
15311            }
15312        }
15313    }
15314    // =========================================================
15315    // BROADCASTS
15316    // =========================================================
15317
15318    private final List getStickiesLocked(String action, IntentFilter filter,
15319            List cur, int userId) {
15320        final ContentResolver resolver = mContext.getContentResolver();
15321        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15322        if (stickies == null) {
15323            return cur;
15324        }
15325        final ArrayList<Intent> list = stickies.get(action);
15326        if (list == null) {
15327            return cur;
15328        }
15329        int N = list.size();
15330        for (int i=0; i<N; i++) {
15331            Intent intent = list.get(i);
15332            if (filter.match(resolver, intent, true, TAG) >= 0) {
15333                if (cur == null) {
15334                    cur = new ArrayList<Intent>();
15335                }
15336                cur.add(intent);
15337            }
15338        }
15339        return cur;
15340    }
15341
15342    boolean isPendingBroadcastProcessLocked(int pid) {
15343        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15344                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15345    }
15346
15347    void skipPendingBroadcastLocked(int pid) {
15348            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15349            for (BroadcastQueue queue : mBroadcastQueues) {
15350                queue.skipPendingBroadcastLocked(pid);
15351            }
15352    }
15353
15354    // The app just attached; send any pending broadcasts that it should receive
15355    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15356        boolean didSomething = false;
15357        for (BroadcastQueue queue : mBroadcastQueues) {
15358            didSomething |= queue.sendPendingBroadcastsLocked(app);
15359        }
15360        return didSomething;
15361    }
15362
15363    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15364            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15365        enforceNotIsolatedCaller("registerReceiver");
15366        int callingUid;
15367        int callingPid;
15368        synchronized(this) {
15369            ProcessRecord callerApp = null;
15370            if (caller != null) {
15371                callerApp = getRecordForAppLocked(caller);
15372                if (callerApp == null) {
15373                    throw new SecurityException(
15374                            "Unable to find app for caller " + caller
15375                            + " (pid=" + Binder.getCallingPid()
15376                            + ") when registering receiver " + receiver);
15377                }
15378                if (callerApp.info.uid != Process.SYSTEM_UID &&
15379                        !callerApp.pkgList.containsKey(callerPackage) &&
15380                        !"android".equals(callerPackage)) {
15381                    throw new SecurityException("Given caller package " + callerPackage
15382                            + " is not running in process " + callerApp);
15383                }
15384                callingUid = callerApp.info.uid;
15385                callingPid = callerApp.pid;
15386            } else {
15387                callerPackage = null;
15388                callingUid = Binder.getCallingUid();
15389                callingPid = Binder.getCallingPid();
15390            }
15391
15392            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15393                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15394
15395            List allSticky = null;
15396
15397            // Look for any matching sticky broadcasts...
15398            Iterator actions = filter.actionsIterator();
15399            if (actions != null) {
15400                while (actions.hasNext()) {
15401                    String action = (String)actions.next();
15402                    allSticky = getStickiesLocked(action, filter, allSticky,
15403                            UserHandle.USER_ALL);
15404                    allSticky = getStickiesLocked(action, filter, allSticky,
15405                            UserHandle.getUserId(callingUid));
15406                }
15407            } else {
15408                allSticky = getStickiesLocked(null, filter, allSticky,
15409                        UserHandle.USER_ALL);
15410                allSticky = getStickiesLocked(null, filter, allSticky,
15411                        UserHandle.getUserId(callingUid));
15412            }
15413
15414            // The first sticky in the list is returned directly back to
15415            // the client.
15416            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15417
15418            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15419                    + ": " + sticky);
15420
15421            if (receiver == null) {
15422                return sticky;
15423            }
15424
15425            ReceiverList rl
15426                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15427            if (rl == null) {
15428                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15429                        userId, receiver);
15430                if (rl.app != null) {
15431                    rl.app.receivers.add(rl);
15432                } else {
15433                    try {
15434                        receiver.asBinder().linkToDeath(rl, 0);
15435                    } catch (RemoteException e) {
15436                        return sticky;
15437                    }
15438                    rl.linkedToDeath = true;
15439                }
15440                mRegisteredReceivers.put(receiver.asBinder(), rl);
15441            } else if (rl.uid != callingUid) {
15442                throw new IllegalArgumentException(
15443                        "Receiver requested to register for uid " + callingUid
15444                        + " was previously registered for uid " + rl.uid);
15445            } else if (rl.pid != callingPid) {
15446                throw new IllegalArgumentException(
15447                        "Receiver requested to register for pid " + callingPid
15448                        + " was previously registered for pid " + rl.pid);
15449            } else if (rl.userId != userId) {
15450                throw new IllegalArgumentException(
15451                        "Receiver requested to register for user " + userId
15452                        + " was previously registered for user " + rl.userId);
15453            }
15454            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15455                    permission, callingUid, userId);
15456            rl.add(bf);
15457            if (!bf.debugCheck()) {
15458                Slog.w(TAG, "==> For Dynamic broadast");
15459            }
15460            mReceiverResolver.addFilter(bf);
15461
15462            // Enqueue broadcasts for all existing stickies that match
15463            // this filter.
15464            if (allSticky != null) {
15465                ArrayList receivers = new ArrayList();
15466                receivers.add(bf);
15467
15468                int N = allSticky.size();
15469                for (int i=0; i<N; i++) {
15470                    Intent intent = (Intent)allSticky.get(i);
15471                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15472                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15473                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15474                            null, null, false, true, true, -1);
15475                    queue.enqueueParallelBroadcastLocked(r);
15476                    queue.scheduleBroadcastsLocked();
15477                }
15478            }
15479
15480            return sticky;
15481        }
15482    }
15483
15484    public void unregisterReceiver(IIntentReceiver receiver) {
15485        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15486
15487        final long origId = Binder.clearCallingIdentity();
15488        try {
15489            boolean doTrim = false;
15490
15491            synchronized(this) {
15492                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15493                if (rl != null) {
15494                    if (rl.curBroadcast != null) {
15495                        BroadcastRecord r = rl.curBroadcast;
15496                        final boolean doNext = finishReceiverLocked(
15497                                receiver.asBinder(), r.resultCode, r.resultData,
15498                                r.resultExtras, r.resultAbort);
15499                        if (doNext) {
15500                            doTrim = true;
15501                            r.queue.processNextBroadcast(false);
15502                        }
15503                    }
15504
15505                    if (rl.app != null) {
15506                        rl.app.receivers.remove(rl);
15507                    }
15508                    removeReceiverLocked(rl);
15509                    if (rl.linkedToDeath) {
15510                        rl.linkedToDeath = false;
15511                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15512                    }
15513                }
15514            }
15515
15516            // If we actually concluded any broadcasts, we might now be able
15517            // to trim the recipients' apps from our working set
15518            if (doTrim) {
15519                trimApplications();
15520                return;
15521            }
15522
15523        } finally {
15524            Binder.restoreCallingIdentity(origId);
15525        }
15526    }
15527
15528    void removeReceiverLocked(ReceiverList rl) {
15529        mRegisteredReceivers.remove(rl.receiver.asBinder());
15530        int N = rl.size();
15531        for (int i=0; i<N; i++) {
15532            mReceiverResolver.removeFilter(rl.get(i));
15533        }
15534    }
15535
15536    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15537        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15538            ProcessRecord r = mLruProcesses.get(i);
15539            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15540                try {
15541                    r.thread.dispatchPackageBroadcast(cmd, packages);
15542                } catch (RemoteException ex) {
15543                }
15544            }
15545        }
15546    }
15547
15548    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15549            int callingUid, int[] users) {
15550        List<ResolveInfo> receivers = null;
15551        try {
15552            HashSet<ComponentName> singleUserReceivers = null;
15553            boolean scannedFirstReceivers = false;
15554            for (int user : users) {
15555                // Skip users that have Shell restrictions
15556                if (callingUid == Process.SHELL_UID
15557                        && getUserManagerLocked().hasUserRestriction(
15558                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15559                    continue;
15560                }
15561                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15562                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15563                if (user != 0 && newReceivers != null) {
15564                    // If this is not the primary user, we need to check for
15565                    // any receivers that should be filtered out.
15566                    for (int i=0; i<newReceivers.size(); i++) {
15567                        ResolveInfo ri = newReceivers.get(i);
15568                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15569                            newReceivers.remove(i);
15570                            i--;
15571                        }
15572                    }
15573                }
15574                if (newReceivers != null && newReceivers.size() == 0) {
15575                    newReceivers = null;
15576                }
15577                if (receivers == null) {
15578                    receivers = newReceivers;
15579                } else if (newReceivers != null) {
15580                    // We need to concatenate the additional receivers
15581                    // found with what we have do far.  This would be easy,
15582                    // but we also need to de-dup any receivers that are
15583                    // singleUser.
15584                    if (!scannedFirstReceivers) {
15585                        // Collect any single user receivers we had already retrieved.
15586                        scannedFirstReceivers = true;
15587                        for (int i=0; i<receivers.size(); i++) {
15588                            ResolveInfo ri = receivers.get(i);
15589                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15590                                ComponentName cn = new ComponentName(
15591                                        ri.activityInfo.packageName, ri.activityInfo.name);
15592                                if (singleUserReceivers == null) {
15593                                    singleUserReceivers = new HashSet<ComponentName>();
15594                                }
15595                                singleUserReceivers.add(cn);
15596                            }
15597                        }
15598                    }
15599                    // Add the new results to the existing results, tracking
15600                    // and de-dupping single user receivers.
15601                    for (int i=0; i<newReceivers.size(); i++) {
15602                        ResolveInfo ri = newReceivers.get(i);
15603                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15604                            ComponentName cn = new ComponentName(
15605                                    ri.activityInfo.packageName, ri.activityInfo.name);
15606                            if (singleUserReceivers == null) {
15607                                singleUserReceivers = new HashSet<ComponentName>();
15608                            }
15609                            if (!singleUserReceivers.contains(cn)) {
15610                                singleUserReceivers.add(cn);
15611                                receivers.add(ri);
15612                            }
15613                        } else {
15614                            receivers.add(ri);
15615                        }
15616                    }
15617                }
15618            }
15619        } catch (RemoteException ex) {
15620            // pm is in same process, this will never happen.
15621        }
15622        return receivers;
15623    }
15624
15625    private final int broadcastIntentLocked(ProcessRecord callerApp,
15626            String callerPackage, Intent intent, String resolvedType,
15627            IIntentReceiver resultTo, int resultCode, String resultData,
15628            Bundle map, String requiredPermission, int appOp,
15629            boolean ordered, boolean sticky, int callingPid, int callingUid,
15630            int userId) {
15631        intent = new Intent(intent);
15632
15633        // By default broadcasts do not go to stopped apps.
15634        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15635
15636        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15637            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15638            + " ordered=" + ordered + " userid=" + userId);
15639        if ((resultTo != null) && !ordered) {
15640            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15641        }
15642
15643        userId = handleIncomingUser(callingPid, callingUid, userId,
15644                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15645
15646        // Make sure that the user who is receiving this broadcast is started.
15647        // If not, we will just skip it.
15648
15649        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15650            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15651                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15652                Slog.w(TAG, "Skipping broadcast of " + intent
15653                        + ": user " + userId + " is stopped");
15654                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15655            }
15656        }
15657
15658        /*
15659         * Prevent non-system code (defined here to be non-persistent
15660         * processes) from sending protected broadcasts.
15661         */
15662        int callingAppId = UserHandle.getAppId(callingUid);
15663        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15664            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15665            || callingAppId == Process.NFC_UID || callingUid == 0) {
15666            // Always okay.
15667        } else if (callerApp == null || !callerApp.persistent) {
15668            try {
15669                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15670                        intent.getAction())) {
15671                    String msg = "Permission Denial: not allowed to send broadcast "
15672                            + intent.getAction() + " from pid="
15673                            + callingPid + ", uid=" + callingUid;
15674                    Slog.w(TAG, msg);
15675                    throw new SecurityException(msg);
15676                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15677                    // Special case for compatibility: we don't want apps to send this,
15678                    // but historically it has not been protected and apps may be using it
15679                    // to poke their own app widget.  So, instead of making it protected,
15680                    // just limit it to the caller.
15681                    if (callerApp == null) {
15682                        String msg = "Permission Denial: not allowed to send broadcast "
15683                                + intent.getAction() + " from unknown caller.";
15684                        Slog.w(TAG, msg);
15685                        throw new SecurityException(msg);
15686                    } else if (intent.getComponent() != null) {
15687                        // They are good enough to send to an explicit component...  verify
15688                        // it is being sent to the calling app.
15689                        if (!intent.getComponent().getPackageName().equals(
15690                                callerApp.info.packageName)) {
15691                            String msg = "Permission Denial: not allowed to send broadcast "
15692                                    + intent.getAction() + " to "
15693                                    + intent.getComponent().getPackageName() + " from "
15694                                    + callerApp.info.packageName;
15695                            Slog.w(TAG, msg);
15696                            throw new SecurityException(msg);
15697                        }
15698                    } else {
15699                        // Limit broadcast to their own package.
15700                        intent.setPackage(callerApp.info.packageName);
15701                    }
15702                }
15703            } catch (RemoteException e) {
15704                Slog.w(TAG, "Remote exception", e);
15705                return ActivityManager.BROADCAST_SUCCESS;
15706            }
15707        }
15708
15709        final String action = intent.getAction();
15710        if (action != null) {
15711            switch (action) {
15712                case Intent.ACTION_UID_REMOVED:
15713                case Intent.ACTION_PACKAGE_REMOVED:
15714                case Intent.ACTION_PACKAGE_CHANGED:
15715                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15716                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15717                    // Handle special intents: if this broadcast is from the package
15718                    // manager about a package being removed, we need to remove all of
15719                    // its activities from the history stack.
15720                    if (checkComponentPermission(
15721                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15722                            callingPid, callingUid, -1, true)
15723                            != PackageManager.PERMISSION_GRANTED) {
15724                        String msg = "Permission Denial: " + intent.getAction()
15725                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15726                                + ", uid=" + callingUid + ")"
15727                                + " requires "
15728                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15729                        Slog.w(TAG, msg);
15730                        throw new SecurityException(msg);
15731                    }
15732                    switch (action) {
15733                        case Intent.ACTION_UID_REMOVED:
15734                            final Bundle intentExtras = intent.getExtras();
15735                            final int uid = intentExtras != null
15736                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15737                            if (uid >= 0) {
15738                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15739                                synchronized (bs) {
15740                                    bs.removeUidStatsLocked(uid);
15741                                }
15742                                mAppOpsService.uidRemoved(uid);
15743                            }
15744                            break;
15745                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15746                            // If resources are unavailable just force stop all those packages
15747                            // and flush the attribute cache as well.
15748                            String list[] =
15749                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15750                            if (list != null && list.length > 0) {
15751                                for (int i = 0; i < list.length; i++) {
15752                                    forceStopPackageLocked(list[i], -1, false, true, true,
15753                                            false, false, userId, "storage unmount");
15754                                }
15755                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15756                                sendPackageBroadcastLocked(
15757                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15758                                        userId);
15759                            }
15760                            break;
15761                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15762                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15763                            break;
15764                        case Intent.ACTION_PACKAGE_REMOVED:
15765                        case Intent.ACTION_PACKAGE_CHANGED:
15766                            Uri data = intent.getData();
15767                            String ssp;
15768                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15769                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15770                                boolean fullUninstall = removed &&
15771                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15772                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15773                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15774                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15775                                            false, true, true, false, fullUninstall, userId,
15776                                            removed ? "pkg removed" : "pkg changed");
15777                                }
15778                                if (removed) {
15779                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15780                                            new String[] {ssp}, userId);
15781                                    if (fullUninstall) {
15782                                        mAppOpsService.packageRemoved(
15783                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15784
15785                                        // Remove all permissions granted from/to this package
15786                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15787
15788                                        removeTasksByPackageNameLocked(ssp, userId);
15789                                    }
15790                                } else {
15791                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15792                                }
15793                            }
15794                            break;
15795                    }
15796                    break;
15797                case Intent.ACTION_PACKAGE_ADDED:
15798                    // Special case for adding a package: by default turn on compatibility mode.
15799                    Uri data = intent.getData();
15800                    String ssp;
15801                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15802                        final boolean replacing =
15803                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15804                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15805
15806                        if (replacing) {
15807                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15808                        }
15809                    }
15810                    break;
15811                case Intent.ACTION_TIMEZONE_CHANGED:
15812                    // If this is the time zone changed action, queue up a message that will reset
15813                    // the timezone of all currently running processes. This message will get
15814                    // queued up before the broadcast happens.
15815                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15816                    break;
15817                case Intent.ACTION_TIME_CHANGED:
15818                    // If the user set the time, let all running processes know.
15819                    final int is24Hour =
15820                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15821                                    : 0;
15822                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15823                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15824                    synchronized (stats) {
15825                        stats.noteCurrentTimeChangedLocked();
15826                    }
15827                    break;
15828                case Intent.ACTION_CLEAR_DNS_CACHE:
15829                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15830                    break;
15831                case Proxy.PROXY_CHANGE_ACTION:
15832                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15833                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15834                    break;
15835            }
15836        }
15837
15838        // Add to the sticky list if requested.
15839        if (sticky) {
15840            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15841                    callingPid, callingUid)
15842                    != PackageManager.PERMISSION_GRANTED) {
15843                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15844                        + callingPid + ", uid=" + callingUid
15845                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15846                Slog.w(TAG, msg);
15847                throw new SecurityException(msg);
15848            }
15849            if (requiredPermission != null) {
15850                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15851                        + " and enforce permission " + requiredPermission);
15852                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15853            }
15854            if (intent.getComponent() != null) {
15855                throw new SecurityException(
15856                        "Sticky broadcasts can't target a specific component");
15857            }
15858            // We use userId directly here, since the "all" target is maintained
15859            // as a separate set of sticky broadcasts.
15860            if (userId != UserHandle.USER_ALL) {
15861                // But first, if this is not a broadcast to all users, then
15862                // make sure it doesn't conflict with an existing broadcast to
15863                // all users.
15864                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15865                        UserHandle.USER_ALL);
15866                if (stickies != null) {
15867                    ArrayList<Intent> list = stickies.get(intent.getAction());
15868                    if (list != null) {
15869                        int N = list.size();
15870                        int i;
15871                        for (i=0; i<N; i++) {
15872                            if (intent.filterEquals(list.get(i))) {
15873                                throw new IllegalArgumentException(
15874                                        "Sticky broadcast " + intent + " for user "
15875                                        + userId + " conflicts with existing global broadcast");
15876                            }
15877                        }
15878                    }
15879                }
15880            }
15881            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15882            if (stickies == null) {
15883                stickies = new ArrayMap<String, ArrayList<Intent>>();
15884                mStickyBroadcasts.put(userId, stickies);
15885            }
15886            ArrayList<Intent> list = stickies.get(intent.getAction());
15887            if (list == null) {
15888                list = new ArrayList<Intent>();
15889                stickies.put(intent.getAction(), list);
15890            }
15891            int N = list.size();
15892            int i;
15893            for (i=0; i<N; i++) {
15894                if (intent.filterEquals(list.get(i))) {
15895                    // This sticky already exists, replace it.
15896                    list.set(i, new Intent(intent));
15897                    break;
15898                }
15899            }
15900            if (i >= N) {
15901                list.add(new Intent(intent));
15902            }
15903        }
15904
15905        int[] users;
15906        if (userId == UserHandle.USER_ALL) {
15907            // Caller wants broadcast to go to all started users.
15908            users = mStartedUserArray;
15909        } else {
15910            // Caller wants broadcast to go to one specific user.
15911            users = new int[] {userId};
15912        }
15913
15914        // Figure out who all will receive this broadcast.
15915        List receivers = null;
15916        List<BroadcastFilter> registeredReceivers = null;
15917        // Need to resolve the intent to interested receivers...
15918        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15919                 == 0) {
15920            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15921        }
15922        if (intent.getComponent() == null) {
15923            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15924                // Query one target user at a time, excluding shell-restricted users
15925                UserManagerService ums = getUserManagerLocked();
15926                for (int i = 0; i < users.length; i++) {
15927                    if (ums.hasUserRestriction(
15928                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15929                        continue;
15930                    }
15931                    List<BroadcastFilter> registeredReceiversForUser =
15932                            mReceiverResolver.queryIntent(intent,
15933                                    resolvedType, false, users[i]);
15934                    if (registeredReceivers == null) {
15935                        registeredReceivers = registeredReceiversForUser;
15936                    } else if (registeredReceiversForUser != null) {
15937                        registeredReceivers.addAll(registeredReceiversForUser);
15938                    }
15939                }
15940            } else {
15941                registeredReceivers = mReceiverResolver.queryIntent(intent,
15942                        resolvedType, false, userId);
15943            }
15944        }
15945
15946        final boolean replacePending =
15947                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15948
15949        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15950                + " replacePending=" + replacePending);
15951
15952        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15953        if (!ordered && NR > 0) {
15954            // If we are not serializing this broadcast, then send the
15955            // registered receivers separately so they don't wait for the
15956            // components to be launched.
15957            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15958            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15959                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15960                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15961                    ordered, sticky, false, userId);
15962            if (DEBUG_BROADCAST) Slog.v(
15963                    TAG, "Enqueueing parallel broadcast " + r);
15964            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15965            if (!replaced) {
15966                queue.enqueueParallelBroadcastLocked(r);
15967                queue.scheduleBroadcastsLocked();
15968            }
15969            registeredReceivers = null;
15970            NR = 0;
15971        }
15972
15973        // Merge into one list.
15974        int ir = 0;
15975        if (receivers != null) {
15976            // A special case for PACKAGE_ADDED: do not allow the package
15977            // being added to see this broadcast.  This prevents them from
15978            // using this as a back door to get run as soon as they are
15979            // installed.  Maybe in the future we want to have a special install
15980            // broadcast or such for apps, but we'd like to deliberately make
15981            // this decision.
15982            String skipPackages[] = null;
15983            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15984                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15985                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15986                Uri data = intent.getData();
15987                if (data != null) {
15988                    String pkgName = data.getSchemeSpecificPart();
15989                    if (pkgName != null) {
15990                        skipPackages = new String[] { pkgName };
15991                    }
15992                }
15993            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15994                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15995            }
15996            if (skipPackages != null && (skipPackages.length > 0)) {
15997                for (String skipPackage : skipPackages) {
15998                    if (skipPackage != null) {
15999                        int NT = receivers.size();
16000                        for (int it=0; it<NT; it++) {
16001                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16002                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16003                                receivers.remove(it);
16004                                it--;
16005                                NT--;
16006                            }
16007                        }
16008                    }
16009                }
16010            }
16011
16012            int NT = receivers != null ? receivers.size() : 0;
16013            int it = 0;
16014            ResolveInfo curt = null;
16015            BroadcastFilter curr = null;
16016            while (it < NT && ir < NR) {
16017                if (curt == null) {
16018                    curt = (ResolveInfo)receivers.get(it);
16019                }
16020                if (curr == null) {
16021                    curr = registeredReceivers.get(ir);
16022                }
16023                if (curr.getPriority() >= curt.priority) {
16024                    // Insert this broadcast record into the final list.
16025                    receivers.add(it, curr);
16026                    ir++;
16027                    curr = null;
16028                    it++;
16029                    NT++;
16030                } else {
16031                    // Skip to the next ResolveInfo in the final list.
16032                    it++;
16033                    curt = null;
16034                }
16035            }
16036        }
16037        while (ir < NR) {
16038            if (receivers == null) {
16039                receivers = new ArrayList();
16040            }
16041            receivers.add(registeredReceivers.get(ir));
16042            ir++;
16043        }
16044
16045        if ((receivers != null && receivers.size() > 0)
16046                || resultTo != null) {
16047            BroadcastQueue queue = broadcastQueueForIntent(intent);
16048            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16049                    callerPackage, callingPid, callingUid, resolvedType,
16050                    requiredPermission, appOp, receivers, resultTo, resultCode,
16051                    resultData, map, ordered, sticky, false, userId);
16052            if (DEBUG_BROADCAST) Slog.v(
16053                    TAG, "Enqueueing ordered broadcast " + r
16054                    + ": prev had " + queue.mOrderedBroadcasts.size());
16055            if (DEBUG_BROADCAST) {
16056                int seq = r.intent.getIntExtra("seq", -1);
16057                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16058            }
16059            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16060            if (!replaced) {
16061                queue.enqueueOrderedBroadcastLocked(r);
16062                queue.scheduleBroadcastsLocked();
16063            }
16064        }
16065
16066        return ActivityManager.BROADCAST_SUCCESS;
16067    }
16068
16069    final Intent verifyBroadcastLocked(Intent intent) {
16070        // Refuse possible leaked file descriptors
16071        if (intent != null && intent.hasFileDescriptors() == true) {
16072            throw new IllegalArgumentException("File descriptors passed in Intent");
16073        }
16074
16075        int flags = intent.getFlags();
16076
16077        if (!mProcessesReady) {
16078            // if the caller really truly claims to know what they're doing, go
16079            // ahead and allow the broadcast without launching any receivers
16080            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16081                intent = new Intent(intent);
16082                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16083            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16084                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16085                        + " before boot completion");
16086                throw new IllegalStateException("Cannot broadcast before boot completed");
16087            }
16088        }
16089
16090        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16091            throw new IllegalArgumentException(
16092                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16093        }
16094
16095        return intent;
16096    }
16097
16098    public final int broadcastIntent(IApplicationThread caller,
16099            Intent intent, String resolvedType, IIntentReceiver resultTo,
16100            int resultCode, String resultData, Bundle map,
16101            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16102        enforceNotIsolatedCaller("broadcastIntent");
16103        synchronized(this) {
16104            intent = verifyBroadcastLocked(intent);
16105
16106            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16107            final int callingPid = Binder.getCallingPid();
16108            final int callingUid = Binder.getCallingUid();
16109            final long origId = Binder.clearCallingIdentity();
16110            int res = broadcastIntentLocked(callerApp,
16111                    callerApp != null ? callerApp.info.packageName : null,
16112                    intent, resolvedType, resultTo,
16113                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16114                    callingPid, callingUid, userId);
16115            Binder.restoreCallingIdentity(origId);
16116            return res;
16117        }
16118    }
16119
16120    int broadcastIntentInPackage(String packageName, int uid,
16121            Intent intent, String resolvedType, IIntentReceiver resultTo,
16122            int resultCode, String resultData, Bundle map,
16123            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16124        synchronized(this) {
16125            intent = verifyBroadcastLocked(intent);
16126
16127            final long origId = Binder.clearCallingIdentity();
16128            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16129                    resultTo, resultCode, resultData, map, requiredPermission,
16130                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16131            Binder.restoreCallingIdentity(origId);
16132            return res;
16133        }
16134    }
16135
16136    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16137        // Refuse possible leaked file descriptors
16138        if (intent != null && intent.hasFileDescriptors() == true) {
16139            throw new IllegalArgumentException("File descriptors passed in Intent");
16140        }
16141
16142        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16143                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16144
16145        synchronized(this) {
16146            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16147                    != PackageManager.PERMISSION_GRANTED) {
16148                String msg = "Permission Denial: unbroadcastIntent() from pid="
16149                        + Binder.getCallingPid()
16150                        + ", uid=" + Binder.getCallingUid()
16151                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16152                Slog.w(TAG, msg);
16153                throw new SecurityException(msg);
16154            }
16155            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16156            if (stickies != null) {
16157                ArrayList<Intent> list = stickies.get(intent.getAction());
16158                if (list != null) {
16159                    int N = list.size();
16160                    int i;
16161                    for (i=0; i<N; i++) {
16162                        if (intent.filterEquals(list.get(i))) {
16163                            list.remove(i);
16164                            break;
16165                        }
16166                    }
16167                    if (list.size() <= 0) {
16168                        stickies.remove(intent.getAction());
16169                    }
16170                }
16171                if (stickies.size() <= 0) {
16172                    mStickyBroadcasts.remove(userId);
16173                }
16174            }
16175        }
16176    }
16177
16178    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16179            String resultData, Bundle resultExtras, boolean resultAbort) {
16180        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16181        if (r == null) {
16182            Slog.w(TAG, "finishReceiver called but not found on queue");
16183            return false;
16184        }
16185
16186        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16187    }
16188
16189    void backgroundServicesFinishedLocked(int userId) {
16190        for (BroadcastQueue queue : mBroadcastQueues) {
16191            queue.backgroundServicesFinishedLocked(userId);
16192        }
16193    }
16194
16195    public void finishReceiver(IBinder who, int resultCode, String resultData,
16196            Bundle resultExtras, boolean resultAbort) {
16197        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16198
16199        // Refuse possible leaked file descriptors
16200        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16201            throw new IllegalArgumentException("File descriptors passed in Bundle");
16202        }
16203
16204        final long origId = Binder.clearCallingIdentity();
16205        try {
16206            boolean doNext = false;
16207            BroadcastRecord r;
16208
16209            synchronized(this) {
16210                r = broadcastRecordForReceiverLocked(who);
16211                if (r != null) {
16212                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16213                        resultData, resultExtras, resultAbort, true);
16214                }
16215            }
16216
16217            if (doNext) {
16218                r.queue.processNextBroadcast(false);
16219            }
16220            trimApplications();
16221        } finally {
16222            Binder.restoreCallingIdentity(origId);
16223        }
16224    }
16225
16226    // =========================================================
16227    // INSTRUMENTATION
16228    // =========================================================
16229
16230    public boolean startInstrumentation(ComponentName className,
16231            String profileFile, int flags, Bundle arguments,
16232            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16233            int userId, String abiOverride) {
16234        enforceNotIsolatedCaller("startInstrumentation");
16235        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16236                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16237        // Refuse possible leaked file descriptors
16238        if (arguments != null && arguments.hasFileDescriptors()) {
16239            throw new IllegalArgumentException("File descriptors passed in Bundle");
16240        }
16241
16242        synchronized(this) {
16243            InstrumentationInfo ii = null;
16244            ApplicationInfo ai = null;
16245            try {
16246                ii = mContext.getPackageManager().getInstrumentationInfo(
16247                    className, STOCK_PM_FLAGS);
16248                ai = AppGlobals.getPackageManager().getApplicationInfo(
16249                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16250            } catch (PackageManager.NameNotFoundException e) {
16251            } catch (RemoteException e) {
16252            }
16253            if (ii == null) {
16254                reportStartInstrumentationFailure(watcher, className,
16255                        "Unable to find instrumentation info for: " + className);
16256                return false;
16257            }
16258            if (ai == null) {
16259                reportStartInstrumentationFailure(watcher, className,
16260                        "Unable to find instrumentation target package: " + ii.targetPackage);
16261                return false;
16262            }
16263
16264            int match = mContext.getPackageManager().checkSignatures(
16265                    ii.targetPackage, ii.packageName);
16266            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16267                String msg = "Permission Denial: starting instrumentation "
16268                        + className + " from pid="
16269                        + Binder.getCallingPid()
16270                        + ", uid=" + Binder.getCallingPid()
16271                        + " not allowed because package " + ii.packageName
16272                        + " does not have a signature matching the target "
16273                        + ii.targetPackage;
16274                reportStartInstrumentationFailure(watcher, className, msg);
16275                throw new SecurityException(msg);
16276            }
16277
16278            final long origId = Binder.clearCallingIdentity();
16279            // Instrumentation can kill and relaunch even persistent processes
16280            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16281                    "start instr");
16282            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16283            app.instrumentationClass = className;
16284            app.instrumentationInfo = ai;
16285            app.instrumentationProfileFile = profileFile;
16286            app.instrumentationArguments = arguments;
16287            app.instrumentationWatcher = watcher;
16288            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16289            app.instrumentationResultClass = className;
16290            Binder.restoreCallingIdentity(origId);
16291        }
16292
16293        return true;
16294    }
16295
16296    /**
16297     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16298     * error to the logs, but if somebody is watching, send the report there too.  This enables
16299     * the "am" command to report errors with more information.
16300     *
16301     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16302     * @param cn The component name of the instrumentation.
16303     * @param report The error report.
16304     */
16305    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16306            ComponentName cn, String report) {
16307        Slog.w(TAG, report);
16308        try {
16309            if (watcher != null) {
16310                Bundle results = new Bundle();
16311                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16312                results.putString("Error", report);
16313                watcher.instrumentationStatus(cn, -1, results);
16314            }
16315        } catch (RemoteException e) {
16316            Slog.w(TAG, e);
16317        }
16318    }
16319
16320    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16321        if (app.instrumentationWatcher != null) {
16322            try {
16323                // NOTE:  IInstrumentationWatcher *must* be oneway here
16324                app.instrumentationWatcher.instrumentationFinished(
16325                    app.instrumentationClass,
16326                    resultCode,
16327                    results);
16328            } catch (RemoteException e) {
16329            }
16330        }
16331        if (app.instrumentationUiAutomationConnection != null) {
16332            try {
16333                app.instrumentationUiAutomationConnection.shutdown();
16334            } catch (RemoteException re) {
16335                /* ignore */
16336            }
16337            // Only a UiAutomation can set this flag and now that
16338            // it is finished we make sure it is reset to its default.
16339            mUserIsMonkey = false;
16340        }
16341        app.instrumentationWatcher = null;
16342        app.instrumentationUiAutomationConnection = null;
16343        app.instrumentationClass = null;
16344        app.instrumentationInfo = null;
16345        app.instrumentationProfileFile = null;
16346        app.instrumentationArguments = null;
16347
16348        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16349                "finished inst");
16350    }
16351
16352    public void finishInstrumentation(IApplicationThread target,
16353            int resultCode, Bundle results) {
16354        int userId = UserHandle.getCallingUserId();
16355        // Refuse possible leaked file descriptors
16356        if (results != null && results.hasFileDescriptors()) {
16357            throw new IllegalArgumentException("File descriptors passed in Intent");
16358        }
16359
16360        synchronized(this) {
16361            ProcessRecord app = getRecordForAppLocked(target);
16362            if (app == null) {
16363                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16364                return;
16365            }
16366            final long origId = Binder.clearCallingIdentity();
16367            finishInstrumentationLocked(app, resultCode, results);
16368            Binder.restoreCallingIdentity(origId);
16369        }
16370    }
16371
16372    // =========================================================
16373    // CONFIGURATION
16374    // =========================================================
16375
16376    public ConfigurationInfo getDeviceConfigurationInfo() {
16377        ConfigurationInfo config = new ConfigurationInfo();
16378        synchronized (this) {
16379            config.reqTouchScreen = mConfiguration.touchscreen;
16380            config.reqKeyboardType = mConfiguration.keyboard;
16381            config.reqNavigation = mConfiguration.navigation;
16382            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16383                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16384                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16385            }
16386            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16387                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16388                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16389            }
16390            config.reqGlEsVersion = GL_ES_VERSION;
16391        }
16392        return config;
16393    }
16394
16395    ActivityStack getFocusedStack() {
16396        return mStackSupervisor.getFocusedStack();
16397    }
16398
16399    public Configuration getConfiguration() {
16400        Configuration ci;
16401        synchronized(this) {
16402            ci = new Configuration(mConfiguration);
16403        }
16404        return ci;
16405    }
16406
16407    public void updatePersistentConfiguration(Configuration values) {
16408        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16409                "updateConfiguration()");
16410        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16411                "updateConfiguration()");
16412        if (values == null) {
16413            throw new NullPointerException("Configuration must not be null");
16414        }
16415
16416        synchronized(this) {
16417            final long origId = Binder.clearCallingIdentity();
16418            updateConfigurationLocked(values, null, true, false);
16419            Binder.restoreCallingIdentity(origId);
16420        }
16421    }
16422
16423    public void updateConfiguration(Configuration values) {
16424        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16425                "updateConfiguration()");
16426
16427        synchronized(this) {
16428            if (values == null && mWindowManager != null) {
16429                // sentinel: fetch the current configuration from the window manager
16430                values = mWindowManager.computeNewConfiguration();
16431            }
16432
16433            if (mWindowManager != null) {
16434                mProcessList.applyDisplaySize(mWindowManager);
16435            }
16436
16437            final long origId = Binder.clearCallingIdentity();
16438            if (values != null) {
16439                Settings.System.clearConfiguration(values);
16440            }
16441            updateConfigurationLocked(values, null, false, false);
16442            Binder.restoreCallingIdentity(origId);
16443        }
16444    }
16445
16446    /**
16447     * Do either or both things: (1) change the current configuration, and (2)
16448     * make sure the given activity is running with the (now) current
16449     * configuration.  Returns true if the activity has been left running, or
16450     * false if <var>starting</var> is being destroyed to match the new
16451     * configuration.
16452     * @param persistent TODO
16453     */
16454    boolean updateConfigurationLocked(Configuration values,
16455            ActivityRecord starting, boolean persistent, boolean initLocale) {
16456        int changes = 0;
16457
16458        if (values != null) {
16459            Configuration newConfig = new Configuration(mConfiguration);
16460            changes = newConfig.updateFrom(values);
16461            if (changes != 0) {
16462                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16463                    Slog.i(TAG, "Updating configuration to: " + values);
16464                }
16465
16466                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16467
16468                if (values.locale != null && !initLocale) {
16469                    saveLocaleLocked(values.locale,
16470                                     !values.locale.equals(mConfiguration.locale),
16471                                     values.userSetLocale);
16472                }
16473
16474                mConfigurationSeq++;
16475                if (mConfigurationSeq <= 0) {
16476                    mConfigurationSeq = 1;
16477                }
16478                newConfig.seq = mConfigurationSeq;
16479                mConfiguration = newConfig;
16480                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16481                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16482                //mUsageStatsService.noteStartConfig(newConfig);
16483
16484                final Configuration configCopy = new Configuration(mConfiguration);
16485
16486                // TODO: If our config changes, should we auto dismiss any currently
16487                // showing dialogs?
16488                mShowDialogs = shouldShowDialogs(newConfig);
16489
16490                AttributeCache ac = AttributeCache.instance();
16491                if (ac != null) {
16492                    ac.updateConfiguration(configCopy);
16493                }
16494
16495                // Make sure all resources in our process are updated
16496                // right now, so that anyone who is going to retrieve
16497                // resource values after we return will be sure to get
16498                // the new ones.  This is especially important during
16499                // boot, where the first config change needs to guarantee
16500                // all resources have that config before following boot
16501                // code is executed.
16502                mSystemThread.applyConfigurationToResources(configCopy);
16503
16504                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16505                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16506                    msg.obj = new Configuration(configCopy);
16507                    mHandler.sendMessage(msg);
16508                }
16509
16510                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16511                    ProcessRecord app = mLruProcesses.get(i);
16512                    try {
16513                        if (app.thread != null) {
16514                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16515                                    + app.processName + " new config " + mConfiguration);
16516                            app.thread.scheduleConfigurationChanged(configCopy);
16517                        }
16518                    } catch (Exception e) {
16519                    }
16520                }
16521                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16522                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16523                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16524                        | Intent.FLAG_RECEIVER_FOREGROUND);
16525                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16526                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16527                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16528                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16529                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16530                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16531                    broadcastIntentLocked(null, null, intent,
16532                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16533                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16534                }
16535            }
16536        }
16537
16538        boolean kept = true;
16539        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16540        // mainStack is null during startup.
16541        if (mainStack != null) {
16542            if (changes != 0 && starting == null) {
16543                // If the configuration changed, and the caller is not already
16544                // in the process of starting an activity, then find the top
16545                // activity to check if its configuration needs to change.
16546                starting = mainStack.topRunningActivityLocked(null);
16547            }
16548
16549            if (starting != null) {
16550                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16551                // And we need to make sure at this point that all other activities
16552                // are made visible with the correct configuration.
16553                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16554            }
16555        }
16556
16557        if (values != null && mWindowManager != null) {
16558            mWindowManager.setNewConfiguration(mConfiguration);
16559        }
16560
16561        return kept;
16562    }
16563
16564    /**
16565     * Decide based on the configuration whether we should shouw the ANR,
16566     * crash, etc dialogs.  The idea is that if there is no affordnace to
16567     * press the on-screen buttons, we shouldn't show the dialog.
16568     *
16569     * A thought: SystemUI might also want to get told about this, the Power
16570     * dialog / global actions also might want different behaviors.
16571     */
16572    private static final boolean shouldShowDialogs(Configuration config) {
16573        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16574                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16575    }
16576
16577    /**
16578     * Save the locale.  You must be inside a synchronized (this) block.
16579     */
16580    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16581        if(isDiff) {
16582            SystemProperties.set("user.language", l.getLanguage());
16583            SystemProperties.set("user.region", l.getCountry());
16584        }
16585
16586        if(isPersist) {
16587            SystemProperties.set("persist.sys.language", l.getLanguage());
16588            SystemProperties.set("persist.sys.country", l.getCountry());
16589            SystemProperties.set("persist.sys.localevar", l.getVariant());
16590
16591            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16592        }
16593    }
16594
16595    @Override
16596    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16597        synchronized (this) {
16598            ActivityRecord srec = ActivityRecord.forToken(token);
16599            if (srec.task != null && srec.task.stack != null) {
16600                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16601            }
16602        }
16603        return false;
16604    }
16605
16606    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16607            Intent resultData) {
16608
16609        synchronized (this) {
16610            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16611            if (stack != null) {
16612                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16613            }
16614            return false;
16615        }
16616    }
16617
16618    public int getLaunchedFromUid(IBinder activityToken) {
16619        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16620        if (srec == null) {
16621            return -1;
16622        }
16623        return srec.launchedFromUid;
16624    }
16625
16626    public String getLaunchedFromPackage(IBinder activityToken) {
16627        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16628        if (srec == null) {
16629            return null;
16630        }
16631        return srec.launchedFromPackage;
16632    }
16633
16634    // =========================================================
16635    // LIFETIME MANAGEMENT
16636    // =========================================================
16637
16638    // Returns which broadcast queue the app is the current [or imminent] receiver
16639    // on, or 'null' if the app is not an active broadcast recipient.
16640    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16641        BroadcastRecord r = app.curReceiver;
16642        if (r != null) {
16643            return r.queue;
16644        }
16645
16646        // It's not the current receiver, but it might be starting up to become one
16647        synchronized (this) {
16648            for (BroadcastQueue queue : mBroadcastQueues) {
16649                r = queue.mPendingBroadcast;
16650                if (r != null && r.curApp == app) {
16651                    // found it; report which queue it's in
16652                    return queue;
16653                }
16654            }
16655        }
16656
16657        return null;
16658    }
16659
16660    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16661            boolean doingAll, long now) {
16662        if (mAdjSeq == app.adjSeq) {
16663            // This adjustment has already been computed.
16664            return app.curRawAdj;
16665        }
16666
16667        if (app.thread == null) {
16668            app.adjSeq = mAdjSeq;
16669            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16670            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16671            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16672        }
16673
16674        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16675        app.adjSource = null;
16676        app.adjTarget = null;
16677        app.empty = false;
16678        app.cached = false;
16679
16680        final int activitiesSize = app.activities.size();
16681
16682        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16683            // The max adjustment doesn't allow this app to be anything
16684            // below foreground, so it is not worth doing work for it.
16685            app.adjType = "fixed";
16686            app.adjSeq = mAdjSeq;
16687            app.curRawAdj = app.maxAdj;
16688            app.foregroundActivities = false;
16689            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16690            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16691            // System processes can do UI, and when they do we want to have
16692            // them trim their memory after the user leaves the UI.  To
16693            // facilitate this, here we need to determine whether or not it
16694            // is currently showing UI.
16695            app.systemNoUi = true;
16696            if (app == TOP_APP) {
16697                app.systemNoUi = false;
16698            } else if (activitiesSize > 0) {
16699                for (int j = 0; j < activitiesSize; j++) {
16700                    final ActivityRecord r = app.activities.get(j);
16701                    if (r.visible) {
16702                        app.systemNoUi = false;
16703                    }
16704                }
16705            }
16706            if (!app.systemNoUi) {
16707                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16708            }
16709            return (app.curAdj=app.maxAdj);
16710        }
16711
16712        app.systemNoUi = false;
16713
16714        // Determine the importance of the process, starting with most
16715        // important to least, and assign an appropriate OOM adjustment.
16716        int adj;
16717        int schedGroup;
16718        int procState;
16719        boolean foregroundActivities = false;
16720        BroadcastQueue queue;
16721        if (app == TOP_APP) {
16722            // The last app on the list is the foreground app.
16723            adj = ProcessList.FOREGROUND_APP_ADJ;
16724            schedGroup = Process.THREAD_GROUP_DEFAULT;
16725            app.adjType = "top-activity";
16726            foregroundActivities = true;
16727            procState = ActivityManager.PROCESS_STATE_TOP;
16728        } else if (app.instrumentationClass != null) {
16729            // Don't want to kill running instrumentation.
16730            adj = ProcessList.FOREGROUND_APP_ADJ;
16731            schedGroup = Process.THREAD_GROUP_DEFAULT;
16732            app.adjType = "instrumentation";
16733            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16734        } else if ((queue = isReceivingBroadcast(app)) != null) {
16735            // An app that is currently receiving a broadcast also
16736            // counts as being in the foreground for OOM killer purposes.
16737            // It's placed in a sched group based on the nature of the
16738            // broadcast as reflected by which queue it's active in.
16739            adj = ProcessList.FOREGROUND_APP_ADJ;
16740            schedGroup = (queue == mFgBroadcastQueue)
16741                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16742            app.adjType = "broadcast";
16743            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16744        } else if (app.executingServices.size() > 0) {
16745            // An app that is currently executing a service callback also
16746            // counts as being in the foreground.
16747            adj = ProcessList.FOREGROUND_APP_ADJ;
16748            schedGroup = app.execServicesFg ?
16749                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16750            app.adjType = "exec-service";
16751            procState = ActivityManager.PROCESS_STATE_SERVICE;
16752            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16753        } else {
16754            // As far as we know the process is empty.  We may change our mind later.
16755            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16756            // At this point we don't actually know the adjustment.  Use the cached adj
16757            // value that the caller wants us to.
16758            adj = cachedAdj;
16759            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16760            app.cached = true;
16761            app.empty = true;
16762            app.adjType = "cch-empty";
16763        }
16764
16765        // Examine all activities if not already foreground.
16766        if (!foregroundActivities && activitiesSize > 0) {
16767            for (int j = 0; j < activitiesSize; j++) {
16768                final ActivityRecord r = app.activities.get(j);
16769                if (r.app != app) {
16770                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16771                            + app + "?!?");
16772                    continue;
16773                }
16774                if (r.visible) {
16775                    // App has a visible activity; only upgrade adjustment.
16776                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16777                        adj = ProcessList.VISIBLE_APP_ADJ;
16778                        app.adjType = "visible";
16779                    }
16780                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16781                        procState = ActivityManager.PROCESS_STATE_TOP;
16782                    }
16783                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16784                    app.cached = false;
16785                    app.empty = false;
16786                    foregroundActivities = true;
16787                    break;
16788                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16789                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16790                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16791                        app.adjType = "pausing";
16792                    }
16793                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16794                        procState = ActivityManager.PROCESS_STATE_TOP;
16795                    }
16796                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16797                    app.cached = false;
16798                    app.empty = false;
16799                    foregroundActivities = true;
16800                } else if (r.state == ActivityState.STOPPING) {
16801                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16802                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16803                        app.adjType = "stopping";
16804                    }
16805                    // For the process state, we will at this point consider the
16806                    // process to be cached.  It will be cached either as an activity
16807                    // or empty depending on whether the activity is finishing.  We do
16808                    // this so that we can treat the process as cached for purposes of
16809                    // memory trimming (determing current memory level, trim command to
16810                    // send to process) since there can be an arbitrary number of stopping
16811                    // processes and they should soon all go into the cached state.
16812                    if (!r.finishing) {
16813                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16814                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16815                        }
16816                    }
16817                    app.cached = false;
16818                    app.empty = false;
16819                    foregroundActivities = true;
16820                } else {
16821                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16822                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16823                        app.adjType = "cch-act";
16824                    }
16825                }
16826            }
16827        }
16828
16829        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16830            if (app.foregroundServices) {
16831                // The user is aware of this app, so make it visible.
16832                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16833                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16834                app.cached = false;
16835                app.adjType = "fg-service";
16836                schedGroup = Process.THREAD_GROUP_DEFAULT;
16837            } else if (app.forcingToForeground != null) {
16838                // The user is aware of this app, so make it visible.
16839                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16840                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16841                app.cached = false;
16842                app.adjType = "force-fg";
16843                app.adjSource = app.forcingToForeground;
16844                schedGroup = Process.THREAD_GROUP_DEFAULT;
16845            }
16846        }
16847
16848        if (app == mHeavyWeightProcess) {
16849            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16850                // We don't want to kill the current heavy-weight process.
16851                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16852                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16853                app.cached = false;
16854                app.adjType = "heavy";
16855            }
16856            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16857                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16858            }
16859        }
16860
16861        if (app == mHomeProcess) {
16862            if (adj > ProcessList.HOME_APP_ADJ) {
16863                // This process is hosting what we currently consider to be the
16864                // home app, so we don't want to let it go into the background.
16865                adj = ProcessList.HOME_APP_ADJ;
16866                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16867                app.cached = false;
16868                app.adjType = "home";
16869            }
16870            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16871                procState = ActivityManager.PROCESS_STATE_HOME;
16872            }
16873        }
16874
16875        if (app == mPreviousProcess && app.activities.size() > 0) {
16876            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16877                // This was the previous process that showed UI to the user.
16878                // We want to try to keep it around more aggressively, to give
16879                // a good experience around switching between two apps.
16880                adj = ProcessList.PREVIOUS_APP_ADJ;
16881                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16882                app.cached = false;
16883                app.adjType = "previous";
16884            }
16885            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16886                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16887            }
16888        }
16889
16890        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16891                + " reason=" + app.adjType);
16892
16893        // By default, we use the computed adjustment.  It may be changed if
16894        // there are applications dependent on our services or providers, but
16895        // this gives us a baseline and makes sure we don't get into an
16896        // infinite recursion.
16897        app.adjSeq = mAdjSeq;
16898        app.curRawAdj = adj;
16899        app.hasStartedServices = false;
16900
16901        if (mBackupTarget != null && app == mBackupTarget.app) {
16902            // If possible we want to avoid killing apps while they're being backed up
16903            if (adj > ProcessList.BACKUP_APP_ADJ) {
16904                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16905                adj = ProcessList.BACKUP_APP_ADJ;
16906                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16907                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16908                }
16909                app.adjType = "backup";
16910                app.cached = false;
16911            }
16912            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16913                procState = ActivityManager.PROCESS_STATE_BACKUP;
16914            }
16915        }
16916
16917        boolean mayBeTop = false;
16918
16919        for (int is = app.services.size()-1;
16920                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16921                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16922                        || procState > ActivityManager.PROCESS_STATE_TOP);
16923                is--) {
16924            ServiceRecord s = app.services.valueAt(is);
16925            if (s.startRequested) {
16926                app.hasStartedServices = true;
16927                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16928                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16929                }
16930                if (app.hasShownUi && app != mHomeProcess) {
16931                    // If this process has shown some UI, let it immediately
16932                    // go to the LRU list because it may be pretty heavy with
16933                    // UI stuff.  We'll tag it with a label just to help
16934                    // debug and understand what is going on.
16935                    if (adj > ProcessList.SERVICE_ADJ) {
16936                        app.adjType = "cch-started-ui-services";
16937                    }
16938                } else {
16939                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16940                        // This service has seen some activity within
16941                        // recent memory, so we will keep its process ahead
16942                        // of the background processes.
16943                        if (adj > ProcessList.SERVICE_ADJ) {
16944                            adj = ProcessList.SERVICE_ADJ;
16945                            app.adjType = "started-services";
16946                            app.cached = false;
16947                        }
16948                    }
16949                    // If we have let the service slide into the background
16950                    // state, still have some text describing what it is doing
16951                    // even though the service no longer has an impact.
16952                    if (adj > ProcessList.SERVICE_ADJ) {
16953                        app.adjType = "cch-started-services";
16954                    }
16955                }
16956            }
16957            for (int conni = s.connections.size()-1;
16958                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16959                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16960                            || procState > ActivityManager.PROCESS_STATE_TOP);
16961                    conni--) {
16962                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16963                for (int i = 0;
16964                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16965                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16966                                || procState > ActivityManager.PROCESS_STATE_TOP);
16967                        i++) {
16968                    // XXX should compute this based on the max of
16969                    // all connected clients.
16970                    ConnectionRecord cr = clist.get(i);
16971                    if (cr.binding.client == app) {
16972                        // Binding to ourself is not interesting.
16973                        continue;
16974                    }
16975                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16976                        ProcessRecord client = cr.binding.client;
16977                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16978                                TOP_APP, doingAll, now);
16979                        int clientProcState = client.curProcState;
16980                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16981                            // If the other app is cached for any reason, for purposes here
16982                            // we are going to consider it empty.  The specific cached state
16983                            // doesn't propagate except under certain conditions.
16984                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16985                        }
16986                        String adjType = null;
16987                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16988                            // Not doing bind OOM management, so treat
16989                            // this guy more like a started service.
16990                            if (app.hasShownUi && app != mHomeProcess) {
16991                                // If this process has shown some UI, let it immediately
16992                                // go to the LRU list because it may be pretty heavy with
16993                                // UI stuff.  We'll tag it with a label just to help
16994                                // debug and understand what is going on.
16995                                if (adj > clientAdj) {
16996                                    adjType = "cch-bound-ui-services";
16997                                }
16998                                app.cached = false;
16999                                clientAdj = adj;
17000                                clientProcState = procState;
17001                            } else {
17002                                if (now >= (s.lastActivity
17003                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17004                                    // This service has not seen activity within
17005                                    // recent memory, so allow it to drop to the
17006                                    // LRU list if there is no other reason to keep
17007                                    // it around.  We'll also tag it with a label just
17008                                    // to help debug and undertand what is going on.
17009                                    if (adj > clientAdj) {
17010                                        adjType = "cch-bound-services";
17011                                    }
17012                                    clientAdj = adj;
17013                                }
17014                            }
17015                        }
17016                        if (adj > clientAdj) {
17017                            // If this process has recently shown UI, and
17018                            // the process that is binding to it is less
17019                            // important than being visible, then we don't
17020                            // care about the binding as much as we care
17021                            // about letting this process get into the LRU
17022                            // list to be killed and restarted if needed for
17023                            // memory.
17024                            if (app.hasShownUi && app != mHomeProcess
17025                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17026                                adjType = "cch-bound-ui-services";
17027                            } else {
17028                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17029                                        |Context.BIND_IMPORTANT)) != 0) {
17030                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17031                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17032                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17033                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17034                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17035                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17036                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17037                                    adj = clientAdj;
17038                                } else {
17039                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17040                                        adj = ProcessList.VISIBLE_APP_ADJ;
17041                                    }
17042                                }
17043                                if (!client.cached) {
17044                                    app.cached = false;
17045                                }
17046                                adjType = "service";
17047                            }
17048                        }
17049                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17050                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17051                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17052                            }
17053                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17054                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17055                                    // Special handling of clients who are in the top state.
17056                                    // We *may* want to consider this process to be in the
17057                                    // top state as well, but only if there is not another
17058                                    // reason for it to be running.  Being on the top is a
17059                                    // special state, meaning you are specifically running
17060                                    // for the current top app.  If the process is already
17061                                    // running in the background for some other reason, it
17062                                    // is more important to continue considering it to be
17063                                    // in the background state.
17064                                    mayBeTop = true;
17065                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17066                                } else {
17067                                    // Special handling for above-top states (persistent
17068                                    // processes).  These should not bring the current process
17069                                    // into the top state, since they are not on top.  Instead
17070                                    // give them the best state after that.
17071                                    clientProcState =
17072                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17073                                }
17074                            }
17075                        } else {
17076                            if (clientProcState <
17077                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17078                                clientProcState =
17079                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17080                            }
17081                        }
17082                        if (procState > clientProcState) {
17083                            procState = clientProcState;
17084                        }
17085                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17086                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17087                            app.pendingUiClean = true;
17088                        }
17089                        if (adjType != null) {
17090                            app.adjType = adjType;
17091                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17092                                    .REASON_SERVICE_IN_USE;
17093                            app.adjSource = cr.binding.client;
17094                            app.adjSourceProcState = clientProcState;
17095                            app.adjTarget = s.name;
17096                        }
17097                    }
17098                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17099                        app.treatLikeActivity = true;
17100                    }
17101                    final ActivityRecord a = cr.activity;
17102                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17103                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17104                                (a.visible || a.state == ActivityState.RESUMED
17105                                 || a.state == ActivityState.PAUSING)) {
17106                            adj = ProcessList.FOREGROUND_APP_ADJ;
17107                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17108                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17109                            }
17110                            app.cached = false;
17111                            app.adjType = "service";
17112                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17113                                    .REASON_SERVICE_IN_USE;
17114                            app.adjSource = a;
17115                            app.adjSourceProcState = procState;
17116                            app.adjTarget = s.name;
17117                        }
17118                    }
17119                }
17120            }
17121        }
17122
17123        for (int provi = app.pubProviders.size()-1;
17124                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17125                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17126                        || procState > ActivityManager.PROCESS_STATE_TOP);
17127                provi--) {
17128            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17129            for (int i = cpr.connections.size()-1;
17130                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17131                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17132                            || procState > ActivityManager.PROCESS_STATE_TOP);
17133                    i--) {
17134                ContentProviderConnection conn = cpr.connections.get(i);
17135                ProcessRecord client = conn.client;
17136                if (client == app) {
17137                    // Being our own client is not interesting.
17138                    continue;
17139                }
17140                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17141                int clientProcState = client.curProcState;
17142                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17143                    // If the other app is cached for any reason, for purposes here
17144                    // we are going to consider it empty.
17145                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17146                }
17147                if (adj > clientAdj) {
17148                    if (app.hasShownUi && app != mHomeProcess
17149                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17150                        app.adjType = "cch-ui-provider";
17151                    } else {
17152                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17153                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17154                        app.adjType = "provider";
17155                    }
17156                    app.cached &= client.cached;
17157                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17158                            .REASON_PROVIDER_IN_USE;
17159                    app.adjSource = client;
17160                    app.adjSourceProcState = clientProcState;
17161                    app.adjTarget = cpr.name;
17162                }
17163                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17164                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17165                        // Special handling of clients who are in the top state.
17166                        // We *may* want to consider this process to be in the
17167                        // top state as well, but only if there is not another
17168                        // reason for it to be running.  Being on the top is a
17169                        // special state, meaning you are specifically running
17170                        // for the current top app.  If the process is already
17171                        // running in the background for some other reason, it
17172                        // is more important to continue considering it to be
17173                        // in the background state.
17174                        mayBeTop = true;
17175                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17176                    } else {
17177                        // Special handling for above-top states (persistent
17178                        // processes).  These should not bring the current process
17179                        // into the top state, since they are not on top.  Instead
17180                        // give them the best state after that.
17181                        clientProcState =
17182                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17183                    }
17184                }
17185                if (procState > clientProcState) {
17186                    procState = clientProcState;
17187                }
17188                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17189                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17190                }
17191            }
17192            // If the provider has external (non-framework) process
17193            // dependencies, ensure that its adjustment is at least
17194            // FOREGROUND_APP_ADJ.
17195            if (cpr.hasExternalProcessHandles()) {
17196                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17197                    adj = ProcessList.FOREGROUND_APP_ADJ;
17198                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17199                    app.cached = false;
17200                    app.adjType = "provider";
17201                    app.adjTarget = cpr.name;
17202                }
17203                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17204                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17205                }
17206            }
17207        }
17208
17209        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17210            // A client of one of our services or providers is in the top state.  We
17211            // *may* want to be in the top state, but not if we are already running in
17212            // the background for some other reason.  For the decision here, we are going
17213            // to pick out a few specific states that we want to remain in when a client
17214            // is top (states that tend to be longer-term) and otherwise allow it to go
17215            // to the top state.
17216            switch (procState) {
17217                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17218                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17219                case ActivityManager.PROCESS_STATE_SERVICE:
17220                    // These all are longer-term states, so pull them up to the top
17221                    // of the background states, but not all the way to the top state.
17222                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17223                    break;
17224                default:
17225                    // Otherwise, top is a better choice, so take it.
17226                    procState = ActivityManager.PROCESS_STATE_TOP;
17227                    break;
17228            }
17229        }
17230
17231        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17232            if (app.hasClientActivities) {
17233                // This is a cached process, but with client activities.  Mark it so.
17234                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17235                app.adjType = "cch-client-act";
17236            } else if (app.treatLikeActivity) {
17237                // This is a cached process, but somebody wants us to treat it like it has
17238                // an activity, okay!
17239                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17240                app.adjType = "cch-as-act";
17241            }
17242        }
17243
17244        if (adj == ProcessList.SERVICE_ADJ) {
17245            if (doingAll) {
17246                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17247                mNewNumServiceProcs++;
17248                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17249                if (!app.serviceb) {
17250                    // This service isn't far enough down on the LRU list to
17251                    // normally be a B service, but if we are low on RAM and it
17252                    // is large we want to force it down since we would prefer to
17253                    // keep launcher over it.
17254                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17255                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17256                        app.serviceHighRam = true;
17257                        app.serviceb = true;
17258                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17259                    } else {
17260                        mNewNumAServiceProcs++;
17261                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17262                    }
17263                } else {
17264                    app.serviceHighRam = false;
17265                }
17266            }
17267            if (app.serviceb) {
17268                adj = ProcessList.SERVICE_B_ADJ;
17269            }
17270        }
17271
17272        app.curRawAdj = adj;
17273
17274        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17275        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17276        if (adj > app.maxAdj) {
17277            adj = app.maxAdj;
17278            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17279                schedGroup = Process.THREAD_GROUP_DEFAULT;
17280            }
17281        }
17282
17283        // Do final modification to adj.  Everything we do between here and applying
17284        // the final setAdj must be done in this function, because we will also use
17285        // it when computing the final cached adj later.  Note that we don't need to
17286        // worry about this for max adj above, since max adj will always be used to
17287        // keep it out of the cached vaues.
17288        app.curAdj = app.modifyRawOomAdj(adj);
17289        app.curSchedGroup = schedGroup;
17290        app.curProcState = procState;
17291        app.foregroundActivities = foregroundActivities;
17292
17293        return app.curRawAdj;
17294    }
17295
17296    /**
17297     * Schedule PSS collection of a process.
17298     */
17299    void requestPssLocked(ProcessRecord proc, int procState) {
17300        if (mPendingPssProcesses.contains(proc)) {
17301            return;
17302        }
17303        if (mPendingPssProcesses.size() == 0) {
17304            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17305        }
17306        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17307        proc.pssProcState = procState;
17308        mPendingPssProcesses.add(proc);
17309    }
17310
17311    /**
17312     * Schedule PSS collection of all processes.
17313     */
17314    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17315        if (!always) {
17316            if (now < (mLastFullPssTime +
17317                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17318                return;
17319            }
17320        }
17321        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17322        mLastFullPssTime = now;
17323        mFullPssPending = true;
17324        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17325        mPendingPssProcesses.clear();
17326        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17327            ProcessRecord app = mLruProcesses.get(i);
17328            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17329                app.pssProcState = app.setProcState;
17330                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17331                        isSleeping(), now);
17332                mPendingPssProcesses.add(app);
17333            }
17334        }
17335        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17336    }
17337
17338    /**
17339     * Ask a given process to GC right now.
17340     */
17341    final void performAppGcLocked(ProcessRecord app) {
17342        try {
17343            app.lastRequestedGc = SystemClock.uptimeMillis();
17344            if (app.thread != null) {
17345                if (app.reportLowMemory) {
17346                    app.reportLowMemory = false;
17347                    app.thread.scheduleLowMemory();
17348                } else {
17349                    app.thread.processInBackground();
17350                }
17351            }
17352        } catch (Exception e) {
17353            // whatever.
17354        }
17355    }
17356
17357    /**
17358     * Returns true if things are idle enough to perform GCs.
17359     */
17360    private final boolean canGcNowLocked() {
17361        boolean processingBroadcasts = false;
17362        for (BroadcastQueue q : mBroadcastQueues) {
17363            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17364                processingBroadcasts = true;
17365            }
17366        }
17367        return !processingBroadcasts
17368                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17369    }
17370
17371    /**
17372     * Perform GCs on all processes that are waiting for it, but only
17373     * if things are idle.
17374     */
17375    final void performAppGcsLocked() {
17376        final int N = mProcessesToGc.size();
17377        if (N <= 0) {
17378            return;
17379        }
17380        if (canGcNowLocked()) {
17381            while (mProcessesToGc.size() > 0) {
17382                ProcessRecord proc = mProcessesToGc.remove(0);
17383                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17384                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17385                            <= SystemClock.uptimeMillis()) {
17386                        // To avoid spamming the system, we will GC processes one
17387                        // at a time, waiting a few seconds between each.
17388                        performAppGcLocked(proc);
17389                        scheduleAppGcsLocked();
17390                        return;
17391                    } else {
17392                        // It hasn't been long enough since we last GCed this
17393                        // process...  put it in the list to wait for its time.
17394                        addProcessToGcListLocked(proc);
17395                        break;
17396                    }
17397                }
17398            }
17399
17400            scheduleAppGcsLocked();
17401        }
17402    }
17403
17404    /**
17405     * If all looks good, perform GCs on all processes waiting for them.
17406     */
17407    final void performAppGcsIfAppropriateLocked() {
17408        if (canGcNowLocked()) {
17409            performAppGcsLocked();
17410            return;
17411        }
17412        // Still not idle, wait some more.
17413        scheduleAppGcsLocked();
17414    }
17415
17416    /**
17417     * Schedule the execution of all pending app GCs.
17418     */
17419    final void scheduleAppGcsLocked() {
17420        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17421
17422        if (mProcessesToGc.size() > 0) {
17423            // Schedule a GC for the time to the next process.
17424            ProcessRecord proc = mProcessesToGc.get(0);
17425            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17426
17427            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17428            long now = SystemClock.uptimeMillis();
17429            if (when < (now+GC_TIMEOUT)) {
17430                when = now + GC_TIMEOUT;
17431            }
17432            mHandler.sendMessageAtTime(msg, when);
17433        }
17434    }
17435
17436    /**
17437     * Add a process to the array of processes waiting to be GCed.  Keeps the
17438     * list in sorted order by the last GC time.  The process can't already be
17439     * on the list.
17440     */
17441    final void addProcessToGcListLocked(ProcessRecord proc) {
17442        boolean added = false;
17443        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17444            if (mProcessesToGc.get(i).lastRequestedGc <
17445                    proc.lastRequestedGc) {
17446                added = true;
17447                mProcessesToGc.add(i+1, proc);
17448                break;
17449            }
17450        }
17451        if (!added) {
17452            mProcessesToGc.add(0, proc);
17453        }
17454    }
17455
17456    /**
17457     * Set up to ask a process to GC itself.  This will either do it
17458     * immediately, or put it on the list of processes to gc the next
17459     * time things are idle.
17460     */
17461    final void scheduleAppGcLocked(ProcessRecord app) {
17462        long now = SystemClock.uptimeMillis();
17463        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17464            return;
17465        }
17466        if (!mProcessesToGc.contains(app)) {
17467            addProcessToGcListLocked(app);
17468            scheduleAppGcsLocked();
17469        }
17470    }
17471
17472    final void checkExcessivePowerUsageLocked(boolean doKills) {
17473        updateCpuStatsNow();
17474
17475        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17476        boolean doWakeKills = doKills;
17477        boolean doCpuKills = doKills;
17478        if (mLastPowerCheckRealtime == 0) {
17479            doWakeKills = false;
17480        }
17481        if (mLastPowerCheckUptime == 0) {
17482            doCpuKills = false;
17483        }
17484        if (stats.isScreenOn()) {
17485            doWakeKills = false;
17486        }
17487        final long curRealtime = SystemClock.elapsedRealtime();
17488        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17489        final long curUptime = SystemClock.uptimeMillis();
17490        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17491        mLastPowerCheckRealtime = curRealtime;
17492        mLastPowerCheckUptime = curUptime;
17493        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17494            doWakeKills = false;
17495        }
17496        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17497            doCpuKills = false;
17498        }
17499        int i = mLruProcesses.size();
17500        while (i > 0) {
17501            i--;
17502            ProcessRecord app = mLruProcesses.get(i);
17503            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17504                long wtime;
17505                synchronized (stats) {
17506                    wtime = stats.getProcessWakeTime(app.info.uid,
17507                            app.pid, curRealtime);
17508                }
17509                long wtimeUsed = wtime - app.lastWakeTime;
17510                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17511                if (DEBUG_POWER) {
17512                    StringBuilder sb = new StringBuilder(128);
17513                    sb.append("Wake for ");
17514                    app.toShortString(sb);
17515                    sb.append(": over ");
17516                    TimeUtils.formatDuration(realtimeSince, sb);
17517                    sb.append(" used ");
17518                    TimeUtils.formatDuration(wtimeUsed, sb);
17519                    sb.append(" (");
17520                    sb.append((wtimeUsed*100)/realtimeSince);
17521                    sb.append("%)");
17522                    Slog.i(TAG, sb.toString());
17523                    sb.setLength(0);
17524                    sb.append("CPU for ");
17525                    app.toShortString(sb);
17526                    sb.append(": over ");
17527                    TimeUtils.formatDuration(uptimeSince, sb);
17528                    sb.append(" used ");
17529                    TimeUtils.formatDuration(cputimeUsed, sb);
17530                    sb.append(" (");
17531                    sb.append((cputimeUsed*100)/uptimeSince);
17532                    sb.append("%)");
17533                    Slog.i(TAG, sb.toString());
17534                }
17535                // If a process has held a wake lock for more
17536                // than 50% of the time during this period,
17537                // that sounds bad.  Kill!
17538                if (doWakeKills && realtimeSince > 0
17539                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17540                    synchronized (stats) {
17541                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17542                                realtimeSince, wtimeUsed);
17543                    }
17544                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17545                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17546                } else if (doCpuKills && uptimeSince > 0
17547                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17548                    synchronized (stats) {
17549                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17550                                uptimeSince, cputimeUsed);
17551                    }
17552                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17553                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17554                } else {
17555                    app.lastWakeTime = wtime;
17556                    app.lastCpuTime = app.curCpuTime;
17557                }
17558            }
17559        }
17560    }
17561
17562    private final boolean applyOomAdjLocked(ProcessRecord app,
17563            ProcessRecord TOP_APP, boolean doingAll, long now) {
17564        boolean success = true;
17565
17566        if (app.curRawAdj != app.setRawAdj) {
17567            app.setRawAdj = app.curRawAdj;
17568        }
17569
17570        int changes = 0;
17571
17572        if (app.curAdj != app.setAdj) {
17573            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17574            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17575                TAG, "Set " + app.pid + " " + app.processName +
17576                " adj " + app.curAdj + ": " + app.adjType);
17577            app.setAdj = app.curAdj;
17578        }
17579
17580        if (app.setSchedGroup != app.curSchedGroup) {
17581            app.setSchedGroup = app.curSchedGroup;
17582            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17583                    "Setting process group of " + app.processName
17584                    + " to " + app.curSchedGroup);
17585            if (app.waitingToKill != null &&
17586                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17587                app.kill(app.waitingToKill, true);
17588                success = false;
17589            } else {
17590                if (true) {
17591                    long oldId = Binder.clearCallingIdentity();
17592                    try {
17593                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17594                    } catch (Exception e) {
17595                        Slog.w(TAG, "Failed setting process group of " + app.pid
17596                                + " to " + app.curSchedGroup);
17597                        e.printStackTrace();
17598                    } finally {
17599                        Binder.restoreCallingIdentity(oldId);
17600                    }
17601                } else {
17602                    if (app.thread != null) {
17603                        try {
17604                            app.thread.setSchedulingGroup(app.curSchedGroup);
17605                        } catch (RemoteException e) {
17606                        }
17607                    }
17608                }
17609                Process.setSwappiness(app.pid,
17610                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17611            }
17612        }
17613        if (app.repForegroundActivities != app.foregroundActivities) {
17614            app.repForegroundActivities = app.foregroundActivities;
17615            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17616        }
17617        if (app.repProcState != app.curProcState) {
17618            app.repProcState = app.curProcState;
17619            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17620            if (app.thread != null) {
17621                try {
17622                    if (false) {
17623                        //RuntimeException h = new RuntimeException("here");
17624                        Slog.i(TAG, "Sending new process state " + app.repProcState
17625                                + " to " + app /*, h*/);
17626                    }
17627                    app.thread.setProcessState(app.repProcState);
17628                } catch (RemoteException e) {
17629                }
17630            }
17631        }
17632        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17633                app.setProcState)) {
17634            app.lastStateTime = now;
17635            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17636                    isSleeping(), now);
17637            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17638                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17639                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17640                    + (app.nextPssTime-now) + ": " + app);
17641        } else {
17642            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17643                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17644                requestPssLocked(app, app.setProcState);
17645                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17646                        isSleeping(), now);
17647            } else if (false && DEBUG_PSS) {
17648                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17649            }
17650        }
17651        if (app.setProcState != app.curProcState) {
17652            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17653                    "Proc state change of " + app.processName
17654                    + " to " + app.curProcState);
17655            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17656            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17657            if (setImportant && !curImportant) {
17658                // This app is no longer something we consider important enough to allow to
17659                // use arbitrary amounts of battery power.  Note
17660                // its current wake lock time to later know to kill it if
17661                // it is not behaving well.
17662                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17663                synchronized (stats) {
17664                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17665                            app.pid, SystemClock.elapsedRealtime());
17666                }
17667                app.lastCpuTime = app.curCpuTime;
17668
17669            }
17670            app.setProcState = app.curProcState;
17671            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17672                app.notCachedSinceIdle = false;
17673            }
17674            if (!doingAll) {
17675                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17676            } else {
17677                app.procStateChanged = true;
17678            }
17679        }
17680
17681        if (changes != 0) {
17682            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17683            int i = mPendingProcessChanges.size()-1;
17684            ProcessChangeItem item = null;
17685            while (i >= 0) {
17686                item = mPendingProcessChanges.get(i);
17687                if (item.pid == app.pid) {
17688                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17689                    break;
17690                }
17691                i--;
17692            }
17693            if (i < 0) {
17694                // No existing item in pending changes; need a new one.
17695                final int NA = mAvailProcessChanges.size();
17696                if (NA > 0) {
17697                    item = mAvailProcessChanges.remove(NA-1);
17698                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17699                } else {
17700                    item = new ProcessChangeItem();
17701                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17702                }
17703                item.changes = 0;
17704                item.pid = app.pid;
17705                item.uid = app.info.uid;
17706                if (mPendingProcessChanges.size() == 0) {
17707                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17708                            "*** Enqueueing dispatch processes changed!");
17709                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17710                }
17711                mPendingProcessChanges.add(item);
17712            }
17713            item.changes |= changes;
17714            item.processState = app.repProcState;
17715            item.foregroundActivities = app.repForegroundActivities;
17716            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17717                    + Integer.toHexString(System.identityHashCode(item))
17718                    + " " + app.toShortString() + ": changes=" + item.changes
17719                    + " procState=" + item.processState
17720                    + " foreground=" + item.foregroundActivities
17721                    + " type=" + app.adjType + " source=" + app.adjSource
17722                    + " target=" + app.adjTarget);
17723        }
17724
17725        return success;
17726    }
17727
17728    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17729        if (proc.thread != null) {
17730            if (proc.baseProcessTracker != null) {
17731                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17732            }
17733            if (proc.repProcState >= 0) {
17734                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17735                        proc.repProcState);
17736            }
17737        }
17738    }
17739
17740    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17741            ProcessRecord TOP_APP, boolean doingAll, long now) {
17742        if (app.thread == null) {
17743            return false;
17744        }
17745
17746        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17747
17748        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17749    }
17750
17751    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17752            boolean oomAdj) {
17753        if (isForeground != proc.foregroundServices) {
17754            proc.foregroundServices = isForeground;
17755            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17756                    proc.info.uid);
17757            if (isForeground) {
17758                if (curProcs == null) {
17759                    curProcs = new ArrayList<ProcessRecord>();
17760                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17761                }
17762                if (!curProcs.contains(proc)) {
17763                    curProcs.add(proc);
17764                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17765                            proc.info.packageName, proc.info.uid);
17766                }
17767            } else {
17768                if (curProcs != null) {
17769                    if (curProcs.remove(proc)) {
17770                        mBatteryStatsService.noteEvent(
17771                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17772                                proc.info.packageName, proc.info.uid);
17773                        if (curProcs.size() <= 0) {
17774                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17775                        }
17776                    }
17777                }
17778            }
17779            if (oomAdj) {
17780                updateOomAdjLocked();
17781            }
17782        }
17783    }
17784
17785    private final ActivityRecord resumedAppLocked() {
17786        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17787        String pkg;
17788        int uid;
17789        if (act != null) {
17790            pkg = act.packageName;
17791            uid = act.info.applicationInfo.uid;
17792        } else {
17793            pkg = null;
17794            uid = -1;
17795        }
17796        // Has the UID or resumed package name changed?
17797        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17798                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17799            if (mCurResumedPackage != null) {
17800                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17801                        mCurResumedPackage, mCurResumedUid);
17802            }
17803            mCurResumedPackage = pkg;
17804            mCurResumedUid = uid;
17805            if (mCurResumedPackage != null) {
17806                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17807                        mCurResumedPackage, mCurResumedUid);
17808            }
17809        }
17810        return act;
17811    }
17812
17813    final boolean updateOomAdjLocked(ProcessRecord app) {
17814        final ActivityRecord TOP_ACT = resumedAppLocked();
17815        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17816        final boolean wasCached = app.cached;
17817
17818        mAdjSeq++;
17819
17820        // This is the desired cached adjusment we want to tell it to use.
17821        // If our app is currently cached, we know it, and that is it.  Otherwise,
17822        // we don't know it yet, and it needs to now be cached we will then
17823        // need to do a complete oom adj.
17824        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17825                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17826        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17827                SystemClock.uptimeMillis());
17828        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17829            // Changed to/from cached state, so apps after it in the LRU
17830            // list may also be changed.
17831            updateOomAdjLocked();
17832        }
17833        return success;
17834    }
17835
17836    final void updateOomAdjLocked() {
17837        final ActivityRecord TOP_ACT = resumedAppLocked();
17838        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17839        final long now = SystemClock.uptimeMillis();
17840        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17841        final int N = mLruProcesses.size();
17842
17843        if (false) {
17844            RuntimeException e = new RuntimeException();
17845            e.fillInStackTrace();
17846            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17847        }
17848
17849        mAdjSeq++;
17850        mNewNumServiceProcs = 0;
17851        mNewNumAServiceProcs = 0;
17852
17853        final int emptyProcessLimit;
17854        final int cachedProcessLimit;
17855        if (mProcessLimit <= 0) {
17856            emptyProcessLimit = cachedProcessLimit = 0;
17857        } else if (mProcessLimit == 1) {
17858            emptyProcessLimit = 1;
17859            cachedProcessLimit = 0;
17860        } else {
17861            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17862            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17863        }
17864
17865        // Let's determine how many processes we have running vs.
17866        // how many slots we have for background processes; we may want
17867        // to put multiple processes in a slot of there are enough of
17868        // them.
17869        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17870                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17871        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17872        if (numEmptyProcs > cachedProcessLimit) {
17873            // If there are more empty processes than our limit on cached
17874            // processes, then use the cached process limit for the factor.
17875            // This ensures that the really old empty processes get pushed
17876            // down to the bottom, so if we are running low on memory we will
17877            // have a better chance at keeping around more cached processes
17878            // instead of a gazillion empty processes.
17879            numEmptyProcs = cachedProcessLimit;
17880        }
17881        int emptyFactor = numEmptyProcs/numSlots;
17882        if (emptyFactor < 1) emptyFactor = 1;
17883        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17884        if (cachedFactor < 1) cachedFactor = 1;
17885        int stepCached = 0;
17886        int stepEmpty = 0;
17887        int numCached = 0;
17888        int numEmpty = 0;
17889        int numTrimming = 0;
17890
17891        mNumNonCachedProcs = 0;
17892        mNumCachedHiddenProcs = 0;
17893
17894        // First update the OOM adjustment for each of the
17895        // application processes based on their current state.
17896        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17897        int nextCachedAdj = curCachedAdj+1;
17898        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17899        int nextEmptyAdj = curEmptyAdj+2;
17900        for (int i=N-1; i>=0; i--) {
17901            ProcessRecord app = mLruProcesses.get(i);
17902            if (!app.killedByAm && app.thread != null) {
17903                app.procStateChanged = false;
17904                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17905
17906                // If we haven't yet assigned the final cached adj
17907                // to the process, do that now.
17908                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17909                    switch (app.curProcState) {
17910                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17911                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17912                            // This process is a cached process holding activities...
17913                            // assign it the next cached value for that type, and then
17914                            // step that cached level.
17915                            app.curRawAdj = curCachedAdj;
17916                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17917                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17918                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17919                                    + ")");
17920                            if (curCachedAdj != nextCachedAdj) {
17921                                stepCached++;
17922                                if (stepCached >= cachedFactor) {
17923                                    stepCached = 0;
17924                                    curCachedAdj = nextCachedAdj;
17925                                    nextCachedAdj += 2;
17926                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17927                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17928                                    }
17929                                }
17930                            }
17931                            break;
17932                        default:
17933                            // For everything else, assign next empty cached process
17934                            // level and bump that up.  Note that this means that
17935                            // long-running services that have dropped down to the
17936                            // cached level will be treated as empty (since their process
17937                            // state is still as a service), which is what we want.
17938                            app.curRawAdj = curEmptyAdj;
17939                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17940                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17941                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17942                                    + ")");
17943                            if (curEmptyAdj != nextEmptyAdj) {
17944                                stepEmpty++;
17945                                if (stepEmpty >= emptyFactor) {
17946                                    stepEmpty = 0;
17947                                    curEmptyAdj = nextEmptyAdj;
17948                                    nextEmptyAdj += 2;
17949                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17950                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17951                                    }
17952                                }
17953                            }
17954                            break;
17955                    }
17956                }
17957
17958                applyOomAdjLocked(app, TOP_APP, true, now);
17959
17960                // Count the number of process types.
17961                switch (app.curProcState) {
17962                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17963                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17964                        mNumCachedHiddenProcs++;
17965                        numCached++;
17966                        if (numCached > cachedProcessLimit) {
17967                            app.kill("cached #" + numCached, true);
17968                        }
17969                        break;
17970                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17971                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17972                                && app.lastActivityTime < oldTime) {
17973                            app.kill("empty for "
17974                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17975                                    / 1000) + "s", true);
17976                        } else {
17977                            numEmpty++;
17978                            if (numEmpty > emptyProcessLimit) {
17979                                app.kill("empty #" + numEmpty, true);
17980                            }
17981                        }
17982                        break;
17983                    default:
17984                        mNumNonCachedProcs++;
17985                        break;
17986                }
17987
17988                if (app.isolated && app.services.size() <= 0) {
17989                    // If this is an isolated process, and there are no
17990                    // services running in it, then the process is no longer
17991                    // needed.  We agressively kill these because we can by
17992                    // definition not re-use the same process again, and it is
17993                    // good to avoid having whatever code was running in them
17994                    // left sitting around after no longer needed.
17995                    app.kill("isolated not needed", true);
17996                }
17997
17998                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17999                        && !app.killedByAm) {
18000                    numTrimming++;
18001                }
18002            }
18003        }
18004
18005        mNumServiceProcs = mNewNumServiceProcs;
18006
18007        // Now determine the memory trimming level of background processes.
18008        // Unfortunately we need to start at the back of the list to do this
18009        // properly.  We only do this if the number of background apps we
18010        // are managing to keep around is less than half the maximum we desire;
18011        // if we are keeping a good number around, we'll let them use whatever
18012        // memory they want.
18013        final int numCachedAndEmpty = numCached + numEmpty;
18014        int memFactor;
18015        if (numCached <= ProcessList.TRIM_CACHED_APPS
18016                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18017            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18018                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18019            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18020                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18021            } else {
18022                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18023            }
18024        } else {
18025            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18026        }
18027        // We always allow the memory level to go up (better).  We only allow it to go
18028        // down if we are in a state where that is allowed, *and* the total number of processes
18029        // has gone down since last time.
18030        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18031                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18032                + " last=" + mLastNumProcesses);
18033        if (memFactor > mLastMemoryLevel) {
18034            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18035                memFactor = mLastMemoryLevel;
18036                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18037            }
18038        }
18039        mLastMemoryLevel = memFactor;
18040        mLastNumProcesses = mLruProcesses.size();
18041        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18042        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18043        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18044            if (mLowRamStartTime == 0) {
18045                mLowRamStartTime = now;
18046            }
18047            int step = 0;
18048            int fgTrimLevel;
18049            switch (memFactor) {
18050                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18051                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18052                    break;
18053                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18054                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18055                    break;
18056                default:
18057                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18058                    break;
18059            }
18060            int factor = numTrimming/3;
18061            int minFactor = 2;
18062            if (mHomeProcess != null) minFactor++;
18063            if (mPreviousProcess != null) minFactor++;
18064            if (factor < minFactor) factor = minFactor;
18065            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18066            for (int i=N-1; i>=0; i--) {
18067                ProcessRecord app = mLruProcesses.get(i);
18068                if (allChanged || app.procStateChanged) {
18069                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18070                    app.procStateChanged = false;
18071                }
18072                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18073                        && !app.killedByAm) {
18074                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18075                        try {
18076                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18077                                    "Trimming memory of " + app.processName
18078                                    + " to " + curLevel);
18079                            app.thread.scheduleTrimMemory(curLevel);
18080                        } catch (RemoteException e) {
18081                        }
18082                        if (false) {
18083                            // For now we won't do this; our memory trimming seems
18084                            // to be good enough at this point that destroying
18085                            // activities causes more harm than good.
18086                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18087                                    && app != mHomeProcess && app != mPreviousProcess) {
18088                                // Need to do this on its own message because the stack may not
18089                                // be in a consistent state at this point.
18090                                // For these apps we will also finish their activities
18091                                // to help them free memory.
18092                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18093                            }
18094                        }
18095                    }
18096                    app.trimMemoryLevel = curLevel;
18097                    step++;
18098                    if (step >= factor) {
18099                        step = 0;
18100                        switch (curLevel) {
18101                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18102                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18103                                break;
18104                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18105                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18106                                break;
18107                        }
18108                    }
18109                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18110                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18111                            && app.thread != null) {
18112                        try {
18113                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18114                                    "Trimming memory of heavy-weight " + app.processName
18115                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18116                            app.thread.scheduleTrimMemory(
18117                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18118                        } catch (RemoteException e) {
18119                        }
18120                    }
18121                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18122                } else {
18123                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18124                            || app.systemNoUi) && app.pendingUiClean) {
18125                        // If this application is now in the background and it
18126                        // had done UI, then give it the special trim level to
18127                        // have it free UI resources.
18128                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18129                        if (app.trimMemoryLevel < level && app.thread != null) {
18130                            try {
18131                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18132                                        "Trimming memory of bg-ui " + app.processName
18133                                        + " to " + level);
18134                                app.thread.scheduleTrimMemory(level);
18135                            } catch (RemoteException e) {
18136                            }
18137                        }
18138                        app.pendingUiClean = false;
18139                    }
18140                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18141                        try {
18142                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18143                                    "Trimming memory of fg " + app.processName
18144                                    + " to " + fgTrimLevel);
18145                            app.thread.scheduleTrimMemory(fgTrimLevel);
18146                        } catch (RemoteException e) {
18147                        }
18148                    }
18149                    app.trimMemoryLevel = fgTrimLevel;
18150                }
18151            }
18152        } else {
18153            if (mLowRamStartTime != 0) {
18154                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18155                mLowRamStartTime = 0;
18156            }
18157            for (int i=N-1; i>=0; i--) {
18158                ProcessRecord app = mLruProcesses.get(i);
18159                if (allChanged || app.procStateChanged) {
18160                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18161                    app.procStateChanged = false;
18162                }
18163                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18164                        || app.systemNoUi) && app.pendingUiClean) {
18165                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18166                            && app.thread != null) {
18167                        try {
18168                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18169                                    "Trimming memory of ui hidden " + app.processName
18170                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18171                            app.thread.scheduleTrimMemory(
18172                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18173                        } catch (RemoteException e) {
18174                        }
18175                    }
18176                    app.pendingUiClean = false;
18177                }
18178                app.trimMemoryLevel = 0;
18179            }
18180        }
18181
18182        if (mAlwaysFinishActivities) {
18183            // Need to do this on its own message because the stack may not
18184            // be in a consistent state at this point.
18185            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18186        }
18187
18188        if (allChanged) {
18189            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18190        }
18191
18192        if (mProcessStats.shouldWriteNowLocked(now)) {
18193            mHandler.post(new Runnable() {
18194                @Override public void run() {
18195                    synchronized (ActivityManagerService.this) {
18196                        mProcessStats.writeStateAsyncLocked();
18197                    }
18198                }
18199            });
18200        }
18201
18202        if (DEBUG_OOM_ADJ) {
18203            if (false) {
18204                RuntimeException here = new RuntimeException("here");
18205                here.fillInStackTrace();
18206                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18207            } else {
18208                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18209            }
18210        }
18211    }
18212
18213    final void trimApplications() {
18214        synchronized (this) {
18215            int i;
18216
18217            // First remove any unused application processes whose package
18218            // has been removed.
18219            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18220                final ProcessRecord app = mRemovedProcesses.get(i);
18221                if (app.activities.size() == 0
18222                        && app.curReceiver == null && app.services.size() == 0) {
18223                    Slog.i(
18224                        TAG, "Exiting empty application process "
18225                        + app.processName + " ("
18226                        + (app.thread != null ? app.thread.asBinder() : null)
18227                        + ")\n");
18228                    if (app.pid > 0 && app.pid != MY_PID) {
18229                        app.kill("empty", false);
18230                    } else {
18231                        try {
18232                            app.thread.scheduleExit();
18233                        } catch (Exception e) {
18234                            // Ignore exceptions.
18235                        }
18236                    }
18237                    cleanUpApplicationRecordLocked(app, false, true, -1);
18238                    mRemovedProcesses.remove(i);
18239
18240                    if (app.persistent) {
18241                        addAppLocked(app.info, false, null /* ABI override */);
18242                    }
18243                }
18244            }
18245
18246            // Now update the oom adj for all processes.
18247            updateOomAdjLocked();
18248        }
18249    }
18250
18251    /** This method sends the specified signal to each of the persistent apps */
18252    public void signalPersistentProcesses(int sig) throws RemoteException {
18253        if (sig != Process.SIGNAL_USR1) {
18254            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18255        }
18256
18257        synchronized (this) {
18258            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18259                    != PackageManager.PERMISSION_GRANTED) {
18260                throw new SecurityException("Requires permission "
18261                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18262            }
18263
18264            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18265                ProcessRecord r = mLruProcesses.get(i);
18266                if (r.thread != null && r.persistent) {
18267                    Process.sendSignal(r.pid, sig);
18268                }
18269            }
18270        }
18271    }
18272
18273    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18274        if (proc == null || proc == mProfileProc) {
18275            proc = mProfileProc;
18276            profileType = mProfileType;
18277            clearProfilerLocked();
18278        }
18279        if (proc == null) {
18280            return;
18281        }
18282        try {
18283            proc.thread.profilerControl(false, null, profileType);
18284        } catch (RemoteException e) {
18285            throw new IllegalStateException("Process disappeared");
18286        }
18287    }
18288
18289    private void clearProfilerLocked() {
18290        if (mProfileFd != null) {
18291            try {
18292                mProfileFd.close();
18293            } catch (IOException e) {
18294            }
18295        }
18296        mProfileApp = null;
18297        mProfileProc = null;
18298        mProfileFile = null;
18299        mProfileType = 0;
18300        mAutoStopProfiler = false;
18301        mSamplingInterval = 0;
18302    }
18303
18304    public boolean profileControl(String process, int userId, boolean start,
18305            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18306
18307        try {
18308            synchronized (this) {
18309                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18310                // its own permission.
18311                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18312                        != PackageManager.PERMISSION_GRANTED) {
18313                    throw new SecurityException("Requires permission "
18314                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18315                }
18316
18317                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18318                    throw new IllegalArgumentException("null profile info or fd");
18319                }
18320
18321                ProcessRecord proc = null;
18322                if (process != null) {
18323                    proc = findProcessLocked(process, userId, "profileControl");
18324                }
18325
18326                if (start && (proc == null || proc.thread == null)) {
18327                    throw new IllegalArgumentException("Unknown process: " + process);
18328                }
18329
18330                if (start) {
18331                    stopProfilerLocked(null, 0);
18332                    setProfileApp(proc.info, proc.processName, profilerInfo);
18333                    mProfileProc = proc;
18334                    mProfileType = profileType;
18335                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18336                    try {
18337                        fd = fd.dup();
18338                    } catch (IOException e) {
18339                        fd = null;
18340                    }
18341                    profilerInfo.profileFd = fd;
18342                    proc.thread.profilerControl(start, profilerInfo, profileType);
18343                    fd = null;
18344                    mProfileFd = null;
18345                } else {
18346                    stopProfilerLocked(proc, profileType);
18347                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18348                        try {
18349                            profilerInfo.profileFd.close();
18350                        } catch (IOException e) {
18351                        }
18352                    }
18353                }
18354
18355                return true;
18356            }
18357        } catch (RemoteException e) {
18358            throw new IllegalStateException("Process disappeared");
18359        } finally {
18360            if (profilerInfo != null && profilerInfo.profileFd != null) {
18361                try {
18362                    profilerInfo.profileFd.close();
18363                } catch (IOException e) {
18364                }
18365            }
18366        }
18367    }
18368
18369    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18370        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18371                userId, true, ALLOW_FULL_ONLY, callName, null);
18372        ProcessRecord proc = null;
18373        try {
18374            int pid = Integer.parseInt(process);
18375            synchronized (mPidsSelfLocked) {
18376                proc = mPidsSelfLocked.get(pid);
18377            }
18378        } catch (NumberFormatException e) {
18379        }
18380
18381        if (proc == null) {
18382            ArrayMap<String, SparseArray<ProcessRecord>> all
18383                    = mProcessNames.getMap();
18384            SparseArray<ProcessRecord> procs = all.get(process);
18385            if (procs != null && procs.size() > 0) {
18386                proc = procs.valueAt(0);
18387                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18388                    for (int i=1; i<procs.size(); i++) {
18389                        ProcessRecord thisProc = procs.valueAt(i);
18390                        if (thisProc.userId == userId) {
18391                            proc = thisProc;
18392                            break;
18393                        }
18394                    }
18395                }
18396            }
18397        }
18398
18399        return proc;
18400    }
18401
18402    public boolean dumpHeap(String process, int userId, boolean managed,
18403            String path, ParcelFileDescriptor fd) throws RemoteException {
18404
18405        try {
18406            synchronized (this) {
18407                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18408                // its own permission (same as profileControl).
18409                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18410                        != PackageManager.PERMISSION_GRANTED) {
18411                    throw new SecurityException("Requires permission "
18412                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18413                }
18414
18415                if (fd == null) {
18416                    throw new IllegalArgumentException("null fd");
18417                }
18418
18419                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18420                if (proc == null || proc.thread == null) {
18421                    throw new IllegalArgumentException("Unknown process: " + process);
18422                }
18423
18424                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18425                if (!isDebuggable) {
18426                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18427                        throw new SecurityException("Process not debuggable: " + proc);
18428                    }
18429                }
18430
18431                proc.thread.dumpHeap(managed, path, fd);
18432                fd = null;
18433                return true;
18434            }
18435        } catch (RemoteException e) {
18436            throw new IllegalStateException("Process disappeared");
18437        } finally {
18438            if (fd != null) {
18439                try {
18440                    fd.close();
18441                } catch (IOException e) {
18442                }
18443            }
18444        }
18445    }
18446
18447    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18448    public void monitor() {
18449        synchronized (this) { }
18450    }
18451
18452    void onCoreSettingsChange(Bundle settings) {
18453        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18454            ProcessRecord processRecord = mLruProcesses.get(i);
18455            try {
18456                if (processRecord.thread != null) {
18457                    processRecord.thread.setCoreSettings(settings);
18458                }
18459            } catch (RemoteException re) {
18460                /* ignore */
18461            }
18462        }
18463    }
18464
18465    // Multi-user methods
18466
18467    /**
18468     * Start user, if its not already running, but don't bring it to foreground.
18469     */
18470    @Override
18471    public boolean startUserInBackground(final int userId) {
18472        return startUser(userId, /* foreground */ false);
18473    }
18474
18475    /**
18476     * Start user, if its not already running, and bring it to foreground.
18477     */
18478    boolean startUserInForeground(final int userId, Dialog dlg) {
18479        boolean result = startUser(userId, /* foreground */ true);
18480        dlg.dismiss();
18481        return result;
18482    }
18483
18484    /**
18485     * Refreshes the list of users related to the current user when either a
18486     * user switch happens or when a new related user is started in the
18487     * background.
18488     */
18489    private void updateCurrentProfileIdsLocked() {
18490        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18491                mCurrentUserId, false /* enabledOnly */);
18492        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18493        for (int i = 0; i < currentProfileIds.length; i++) {
18494            currentProfileIds[i] = profiles.get(i).id;
18495        }
18496        mCurrentProfileIds = currentProfileIds;
18497
18498        synchronized (mUserProfileGroupIdsSelfLocked) {
18499            mUserProfileGroupIdsSelfLocked.clear();
18500            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18501            for (int i = 0; i < users.size(); i++) {
18502                UserInfo user = users.get(i);
18503                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18504                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18505                }
18506            }
18507        }
18508    }
18509
18510    private Set getProfileIdsLocked(int userId) {
18511        Set userIds = new HashSet<Integer>();
18512        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18513                userId, false /* enabledOnly */);
18514        for (UserInfo user : profiles) {
18515            userIds.add(Integer.valueOf(user.id));
18516        }
18517        return userIds;
18518    }
18519
18520    @Override
18521    public boolean switchUser(final int userId) {
18522        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18523        String userName;
18524        synchronized (this) {
18525            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18526            if (userInfo == null) {
18527                Slog.w(TAG, "No user info for user #" + userId);
18528                return false;
18529            }
18530            if (userInfo.isManagedProfile()) {
18531                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18532                return false;
18533            }
18534            userName = userInfo.name;
18535            mTargetUserId = userId;
18536        }
18537        mHandler.removeMessages(START_USER_SWITCH_MSG);
18538        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18539        return true;
18540    }
18541
18542    private void showUserSwitchDialog(int userId, String userName) {
18543        // The dialog will show and then initiate the user switch by calling startUserInForeground
18544        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18545                true /* above system */);
18546        d.show();
18547    }
18548
18549    private boolean startUser(final int userId, final boolean foreground) {
18550        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18551                != PackageManager.PERMISSION_GRANTED) {
18552            String msg = "Permission Denial: switchUser() from pid="
18553                    + Binder.getCallingPid()
18554                    + ", uid=" + Binder.getCallingUid()
18555                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18556            Slog.w(TAG, msg);
18557            throw new SecurityException(msg);
18558        }
18559
18560        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18561
18562        final long ident = Binder.clearCallingIdentity();
18563        try {
18564            synchronized (this) {
18565                final int oldUserId = mCurrentUserId;
18566                if (oldUserId == userId) {
18567                    return true;
18568                }
18569
18570                mStackSupervisor.setLockTaskModeLocked(null, false);
18571
18572                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18573                if (userInfo == null) {
18574                    Slog.w(TAG, "No user info for user #" + userId);
18575                    return false;
18576                }
18577                if (foreground && userInfo.isManagedProfile()) {
18578                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18579                    return false;
18580                }
18581
18582                if (foreground) {
18583                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18584                            R.anim.screen_user_enter);
18585                }
18586
18587                boolean needStart = false;
18588
18589                // If the user we are switching to is not currently started, then
18590                // we need to start it now.
18591                if (mStartedUsers.get(userId) == null) {
18592                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18593                    updateStartedUserArrayLocked();
18594                    needStart = true;
18595                }
18596
18597                final Integer userIdInt = Integer.valueOf(userId);
18598                mUserLru.remove(userIdInt);
18599                mUserLru.add(userIdInt);
18600
18601                if (foreground) {
18602                    mCurrentUserId = userId;
18603                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18604                    updateCurrentProfileIdsLocked();
18605                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18606                    // Once the internal notion of the active user has switched, we lock the device
18607                    // with the option to show the user switcher on the keyguard.
18608                    mWindowManager.lockNow(null);
18609                } else {
18610                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18611                    updateCurrentProfileIdsLocked();
18612                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18613                    mUserLru.remove(currentUserIdInt);
18614                    mUserLru.add(currentUserIdInt);
18615                }
18616
18617                final UserStartedState uss = mStartedUsers.get(userId);
18618
18619                // Make sure user is in the started state.  If it is currently
18620                // stopping, we need to knock that off.
18621                if (uss.mState == UserStartedState.STATE_STOPPING) {
18622                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18623                    // so we can just fairly silently bring the user back from
18624                    // the almost-dead.
18625                    uss.mState = UserStartedState.STATE_RUNNING;
18626                    updateStartedUserArrayLocked();
18627                    needStart = true;
18628                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18629                    // This means ACTION_SHUTDOWN has been sent, so we will
18630                    // need to treat this as a new boot of the user.
18631                    uss.mState = UserStartedState.STATE_BOOTING;
18632                    updateStartedUserArrayLocked();
18633                    needStart = true;
18634                }
18635
18636                if (uss.mState == UserStartedState.STATE_BOOTING) {
18637                    // Booting up a new user, need to tell system services about it.
18638                    // Note that this is on the same handler as scheduling of broadcasts,
18639                    // which is important because it needs to go first.
18640                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18641                }
18642
18643                if (foreground) {
18644                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18645                            oldUserId));
18646                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18647                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18648                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18649                            oldUserId, userId, uss));
18650                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18651                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18652                }
18653
18654                if (needStart) {
18655                    // Send USER_STARTED broadcast
18656                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18657                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18658                            | Intent.FLAG_RECEIVER_FOREGROUND);
18659                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18660                    broadcastIntentLocked(null, null, intent,
18661                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18662                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18663                }
18664
18665                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18666                    if (userId != UserHandle.USER_OWNER) {
18667                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18668                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18669                        broadcastIntentLocked(null, null, intent, null,
18670                                new IIntentReceiver.Stub() {
18671                                    public void performReceive(Intent intent, int resultCode,
18672                                            String data, Bundle extras, boolean ordered,
18673                                            boolean sticky, int sendingUser) {
18674                                        onUserInitialized(uss, foreground, oldUserId, userId);
18675                                    }
18676                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18677                                true, false, MY_PID, Process.SYSTEM_UID,
18678                                userId);
18679                        uss.initializing = true;
18680                    } else {
18681                        getUserManagerLocked().makeInitialized(userInfo.id);
18682                    }
18683                }
18684
18685                if (foreground) {
18686                    if (!uss.initializing) {
18687                        moveUserToForeground(uss, oldUserId, userId);
18688                    }
18689                } else {
18690                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18691                }
18692
18693                if (needStart) {
18694                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18695                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18696                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18697                    broadcastIntentLocked(null, null, intent,
18698                            null, new IIntentReceiver.Stub() {
18699                                @Override
18700                                public void performReceive(Intent intent, int resultCode, String data,
18701                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18702                                        throws RemoteException {
18703                                }
18704                            }, 0, null, null,
18705                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18706                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18707                }
18708            }
18709        } finally {
18710            Binder.restoreCallingIdentity(ident);
18711        }
18712
18713        return true;
18714    }
18715
18716    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18717        long ident = Binder.clearCallingIdentity();
18718        try {
18719            Intent intent;
18720            if (oldUserId >= 0) {
18721                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18722                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18723                int count = profiles.size();
18724                for (int i = 0; i < count; i++) {
18725                    int profileUserId = profiles.get(i).id;
18726                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18727                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18728                            | Intent.FLAG_RECEIVER_FOREGROUND);
18729                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18730                    broadcastIntentLocked(null, null, intent,
18731                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18732                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18733                }
18734            }
18735            if (newUserId >= 0) {
18736                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18737                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18738                int count = profiles.size();
18739                for (int i = 0; i < count; i++) {
18740                    int profileUserId = profiles.get(i).id;
18741                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18742                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18743                            | Intent.FLAG_RECEIVER_FOREGROUND);
18744                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18745                    broadcastIntentLocked(null, null, intent,
18746                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18747                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18748                }
18749                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18750                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18751                        | Intent.FLAG_RECEIVER_FOREGROUND);
18752                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18753                broadcastIntentLocked(null, null, intent,
18754                        null, null, 0, null, null,
18755                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18756                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18757            }
18758        } finally {
18759            Binder.restoreCallingIdentity(ident);
18760        }
18761    }
18762
18763    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18764            final int newUserId) {
18765        final int N = mUserSwitchObservers.beginBroadcast();
18766        if (N > 0) {
18767            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18768                int mCount = 0;
18769                @Override
18770                public void sendResult(Bundle data) throws RemoteException {
18771                    synchronized (ActivityManagerService.this) {
18772                        if (mCurUserSwitchCallback == this) {
18773                            mCount++;
18774                            if (mCount == N) {
18775                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18776                            }
18777                        }
18778                    }
18779                }
18780            };
18781            synchronized (this) {
18782                uss.switching = true;
18783                mCurUserSwitchCallback = callback;
18784            }
18785            for (int i=0; i<N; i++) {
18786                try {
18787                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18788                            newUserId, callback);
18789                } catch (RemoteException e) {
18790                }
18791            }
18792        } else {
18793            synchronized (this) {
18794                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18795            }
18796        }
18797        mUserSwitchObservers.finishBroadcast();
18798    }
18799
18800    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18801        synchronized (this) {
18802            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18803            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18804        }
18805    }
18806
18807    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18808        mCurUserSwitchCallback = null;
18809        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18810        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18811                oldUserId, newUserId, uss));
18812    }
18813
18814    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18815        synchronized (this) {
18816            if (foreground) {
18817                moveUserToForeground(uss, oldUserId, newUserId);
18818            }
18819        }
18820
18821        completeSwitchAndInitalize(uss, newUserId, true, false);
18822    }
18823
18824    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18825        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18826        if (homeInFront) {
18827            startHomeActivityLocked(newUserId);
18828        } else {
18829            mStackSupervisor.resumeTopActivitiesLocked();
18830        }
18831        EventLogTags.writeAmSwitchUser(newUserId);
18832        getUserManagerLocked().userForeground(newUserId);
18833        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18834    }
18835
18836    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18837        completeSwitchAndInitalize(uss, newUserId, false, true);
18838    }
18839
18840    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18841            boolean clearInitializing, boolean clearSwitching) {
18842        boolean unfrozen = false;
18843        synchronized (this) {
18844            if (clearInitializing) {
18845                uss.initializing = false;
18846                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18847            }
18848            if (clearSwitching) {
18849                uss.switching = false;
18850            }
18851            if (!uss.switching && !uss.initializing) {
18852                mWindowManager.stopFreezingScreen();
18853                unfrozen = true;
18854            }
18855        }
18856        if (unfrozen) {
18857            final int N = mUserSwitchObservers.beginBroadcast();
18858            for (int i=0; i<N; i++) {
18859                try {
18860                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18861                } catch (RemoteException e) {
18862                }
18863            }
18864            mUserSwitchObservers.finishBroadcast();
18865        }
18866    }
18867
18868    void scheduleStartProfilesLocked() {
18869        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18870            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18871                    DateUtils.SECOND_IN_MILLIS);
18872        }
18873    }
18874
18875    void startProfilesLocked() {
18876        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18877        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18878                mCurrentUserId, false /* enabledOnly */);
18879        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18880        for (UserInfo user : profiles) {
18881            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18882                    && user.id != mCurrentUserId) {
18883                toStart.add(user);
18884            }
18885        }
18886        final int n = toStart.size();
18887        int i = 0;
18888        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18889            startUserInBackground(toStart.get(i).id);
18890        }
18891        if (i < n) {
18892            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18893        }
18894    }
18895
18896    void finishUserBoot(UserStartedState uss) {
18897        synchronized (this) {
18898            if (uss.mState == UserStartedState.STATE_BOOTING
18899                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18900                uss.mState = UserStartedState.STATE_RUNNING;
18901                final int userId = uss.mHandle.getIdentifier();
18902                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18903                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18904                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18905                broadcastIntentLocked(null, null, intent,
18906                        null, null, 0, null, null,
18907                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18908                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18909            }
18910        }
18911    }
18912
18913    void finishUserSwitch(UserStartedState uss) {
18914        synchronized (this) {
18915            finishUserBoot(uss);
18916
18917            startProfilesLocked();
18918
18919            int num = mUserLru.size();
18920            int i = 0;
18921            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18922                Integer oldUserId = mUserLru.get(i);
18923                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18924                if (oldUss == null) {
18925                    // Shouldn't happen, but be sane if it does.
18926                    mUserLru.remove(i);
18927                    num--;
18928                    continue;
18929                }
18930                if (oldUss.mState == UserStartedState.STATE_STOPPING
18931                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18932                    // This user is already stopping, doesn't count.
18933                    num--;
18934                    i++;
18935                    continue;
18936                }
18937                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18938                    // Owner and current can't be stopped, but count as running.
18939                    i++;
18940                    continue;
18941                }
18942                // This is a user to be stopped.
18943                stopUserLocked(oldUserId, null);
18944                num--;
18945                i++;
18946            }
18947        }
18948    }
18949
18950    @Override
18951    public int stopUser(final int userId, final IStopUserCallback callback) {
18952        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18953                != PackageManager.PERMISSION_GRANTED) {
18954            String msg = "Permission Denial: switchUser() from pid="
18955                    + Binder.getCallingPid()
18956                    + ", uid=" + Binder.getCallingUid()
18957                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18958            Slog.w(TAG, msg);
18959            throw new SecurityException(msg);
18960        }
18961        if (userId <= 0) {
18962            throw new IllegalArgumentException("Can't stop primary user " + userId);
18963        }
18964        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18965        synchronized (this) {
18966            return stopUserLocked(userId, callback);
18967        }
18968    }
18969
18970    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18971        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18972        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18973            return ActivityManager.USER_OP_IS_CURRENT;
18974        }
18975
18976        final UserStartedState uss = mStartedUsers.get(userId);
18977        if (uss == null) {
18978            // User is not started, nothing to do...  but we do need to
18979            // callback if requested.
18980            if (callback != null) {
18981                mHandler.post(new Runnable() {
18982                    @Override
18983                    public void run() {
18984                        try {
18985                            callback.userStopped(userId);
18986                        } catch (RemoteException e) {
18987                        }
18988                    }
18989                });
18990            }
18991            return ActivityManager.USER_OP_SUCCESS;
18992        }
18993
18994        if (callback != null) {
18995            uss.mStopCallbacks.add(callback);
18996        }
18997
18998        if (uss.mState != UserStartedState.STATE_STOPPING
18999                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19000            uss.mState = UserStartedState.STATE_STOPPING;
19001            updateStartedUserArrayLocked();
19002
19003            long ident = Binder.clearCallingIdentity();
19004            try {
19005                // We are going to broadcast ACTION_USER_STOPPING and then
19006                // once that is done send a final ACTION_SHUTDOWN and then
19007                // stop the user.
19008                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19009                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19010                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19011                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19012                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19013                // This is the result receiver for the final shutdown broadcast.
19014                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19015                    @Override
19016                    public void performReceive(Intent intent, int resultCode, String data,
19017                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19018                        finishUserStop(uss);
19019                    }
19020                };
19021                // This is the result receiver for the initial stopping broadcast.
19022                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19023                    @Override
19024                    public void performReceive(Intent intent, int resultCode, String data,
19025                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19026                        // On to the next.
19027                        synchronized (ActivityManagerService.this) {
19028                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19029                                // Whoops, we are being started back up.  Abort, abort!
19030                                return;
19031                            }
19032                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19033                        }
19034                        mBatteryStatsService.noteEvent(
19035                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19036                                Integer.toString(userId), userId);
19037                        mSystemServiceManager.stopUser(userId);
19038                        broadcastIntentLocked(null, null, shutdownIntent,
19039                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19040                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19041                    }
19042                };
19043                // Kick things off.
19044                broadcastIntentLocked(null, null, stoppingIntent,
19045                        null, stoppingReceiver, 0, null, null,
19046                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19047                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19048            } finally {
19049                Binder.restoreCallingIdentity(ident);
19050            }
19051        }
19052
19053        return ActivityManager.USER_OP_SUCCESS;
19054    }
19055
19056    void finishUserStop(UserStartedState uss) {
19057        final int userId = uss.mHandle.getIdentifier();
19058        boolean stopped;
19059        ArrayList<IStopUserCallback> callbacks;
19060        synchronized (this) {
19061            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19062            if (mStartedUsers.get(userId) != uss) {
19063                stopped = false;
19064            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19065                stopped = false;
19066            } else {
19067                stopped = true;
19068                // User can no longer run.
19069                mStartedUsers.remove(userId);
19070                mUserLru.remove(Integer.valueOf(userId));
19071                updateStartedUserArrayLocked();
19072
19073                // Clean up all state and processes associated with the user.
19074                // Kill all the processes for the user.
19075                forceStopUserLocked(userId, "finish user");
19076            }
19077
19078            // Explicitly remove the old information in mRecentTasks.
19079            removeRecentTasksForUserLocked(userId);
19080        }
19081
19082        for (int i=0; i<callbacks.size(); i++) {
19083            try {
19084                if (stopped) callbacks.get(i).userStopped(userId);
19085                else callbacks.get(i).userStopAborted(userId);
19086            } catch (RemoteException e) {
19087            }
19088        }
19089
19090        if (stopped) {
19091            mSystemServiceManager.cleanupUser(userId);
19092            synchronized (this) {
19093                mStackSupervisor.removeUserLocked(userId);
19094            }
19095        }
19096    }
19097
19098    @Override
19099    public UserInfo getCurrentUser() {
19100        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19101                != PackageManager.PERMISSION_GRANTED) && (
19102                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19103                != PackageManager.PERMISSION_GRANTED)) {
19104            String msg = "Permission Denial: getCurrentUser() from pid="
19105                    + Binder.getCallingPid()
19106                    + ", uid=" + Binder.getCallingUid()
19107                    + " requires " + INTERACT_ACROSS_USERS;
19108            Slog.w(TAG, msg);
19109            throw new SecurityException(msg);
19110        }
19111        synchronized (this) {
19112            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19113            return getUserManagerLocked().getUserInfo(userId);
19114        }
19115    }
19116
19117    int getCurrentUserIdLocked() {
19118        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19119    }
19120
19121    @Override
19122    public boolean isUserRunning(int userId, boolean orStopped) {
19123        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19124                != PackageManager.PERMISSION_GRANTED) {
19125            String msg = "Permission Denial: isUserRunning() from pid="
19126                    + Binder.getCallingPid()
19127                    + ", uid=" + Binder.getCallingUid()
19128                    + " requires " + INTERACT_ACROSS_USERS;
19129            Slog.w(TAG, msg);
19130            throw new SecurityException(msg);
19131        }
19132        synchronized (this) {
19133            return isUserRunningLocked(userId, orStopped);
19134        }
19135    }
19136
19137    boolean isUserRunningLocked(int userId, boolean orStopped) {
19138        UserStartedState state = mStartedUsers.get(userId);
19139        if (state == null) {
19140            return false;
19141        }
19142        if (orStopped) {
19143            return true;
19144        }
19145        return state.mState != UserStartedState.STATE_STOPPING
19146                && state.mState != UserStartedState.STATE_SHUTDOWN;
19147    }
19148
19149    @Override
19150    public int[] getRunningUserIds() {
19151        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19152                != PackageManager.PERMISSION_GRANTED) {
19153            String msg = "Permission Denial: isUserRunning() from pid="
19154                    + Binder.getCallingPid()
19155                    + ", uid=" + Binder.getCallingUid()
19156                    + " requires " + INTERACT_ACROSS_USERS;
19157            Slog.w(TAG, msg);
19158            throw new SecurityException(msg);
19159        }
19160        synchronized (this) {
19161            return mStartedUserArray;
19162        }
19163    }
19164
19165    private void updateStartedUserArrayLocked() {
19166        int num = 0;
19167        for (int i=0; i<mStartedUsers.size();  i++) {
19168            UserStartedState uss = mStartedUsers.valueAt(i);
19169            // This list does not include stopping users.
19170            if (uss.mState != UserStartedState.STATE_STOPPING
19171                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19172                num++;
19173            }
19174        }
19175        mStartedUserArray = new int[num];
19176        num = 0;
19177        for (int i=0; i<mStartedUsers.size();  i++) {
19178            UserStartedState uss = mStartedUsers.valueAt(i);
19179            if (uss.mState != UserStartedState.STATE_STOPPING
19180                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19181                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19182                num++;
19183            }
19184        }
19185    }
19186
19187    @Override
19188    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19189        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19190                != PackageManager.PERMISSION_GRANTED) {
19191            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19192                    + Binder.getCallingPid()
19193                    + ", uid=" + Binder.getCallingUid()
19194                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19195            Slog.w(TAG, msg);
19196            throw new SecurityException(msg);
19197        }
19198
19199        mUserSwitchObservers.register(observer);
19200    }
19201
19202    @Override
19203    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19204        mUserSwitchObservers.unregister(observer);
19205    }
19206
19207    private boolean userExists(int userId) {
19208        if (userId == 0) {
19209            return true;
19210        }
19211        UserManagerService ums = getUserManagerLocked();
19212        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19213    }
19214
19215    int[] getUsersLocked() {
19216        UserManagerService ums = getUserManagerLocked();
19217        return ums != null ? ums.getUserIds() : new int[] { 0 };
19218    }
19219
19220    UserManagerService getUserManagerLocked() {
19221        if (mUserManager == null) {
19222            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19223            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19224        }
19225        return mUserManager;
19226    }
19227
19228    private int applyUserId(int uid, int userId) {
19229        return UserHandle.getUid(userId, uid);
19230    }
19231
19232    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19233        if (info == null) return null;
19234        ApplicationInfo newInfo = new ApplicationInfo(info);
19235        newInfo.uid = applyUserId(info.uid, userId);
19236        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19237                + info.packageName;
19238        return newInfo;
19239    }
19240
19241    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19242        if (aInfo == null
19243                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19244            return aInfo;
19245        }
19246
19247        ActivityInfo info = new ActivityInfo(aInfo);
19248        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19249        return info;
19250    }
19251
19252    private final class LocalService extends ActivityManagerInternal {
19253        @Override
19254        public void onWakefulnessChanged(int wakefulness) {
19255            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19256        }
19257
19258        @Override
19259        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19260                String processName, String abiOverride, int uid, Runnable crashHandler) {
19261            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19262                    processName, abiOverride, uid, crashHandler);
19263        }
19264    }
19265
19266    /**
19267     * An implementation of IAppTask, that allows an app to manage its own tasks via
19268     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19269     * only the process that calls getAppTasks() can call the AppTask methods.
19270     */
19271    class AppTaskImpl extends IAppTask.Stub {
19272        private int mTaskId;
19273        private int mCallingUid;
19274
19275        public AppTaskImpl(int taskId, int callingUid) {
19276            mTaskId = taskId;
19277            mCallingUid = callingUid;
19278        }
19279
19280        private void checkCaller() {
19281            if (mCallingUid != Binder.getCallingUid()) {
19282                throw new SecurityException("Caller " + mCallingUid
19283                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19284            }
19285        }
19286
19287        @Override
19288        public void finishAndRemoveTask() {
19289            checkCaller();
19290
19291            synchronized (ActivityManagerService.this) {
19292                long origId = Binder.clearCallingIdentity();
19293                try {
19294                    if (!removeTaskByIdLocked(mTaskId, false)) {
19295                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19296                    }
19297                } finally {
19298                    Binder.restoreCallingIdentity(origId);
19299                }
19300            }
19301        }
19302
19303        @Override
19304        public ActivityManager.RecentTaskInfo getTaskInfo() {
19305            checkCaller();
19306
19307            synchronized (ActivityManagerService.this) {
19308                long origId = Binder.clearCallingIdentity();
19309                try {
19310                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19311                    if (tr == null) {
19312                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19313                    }
19314                    return createRecentTaskInfoFromTaskRecord(tr);
19315                } finally {
19316                    Binder.restoreCallingIdentity(origId);
19317                }
19318            }
19319        }
19320
19321        @Override
19322        public void moveToFront() {
19323            checkCaller();
19324
19325            final TaskRecord tr;
19326            synchronized (ActivityManagerService.this) {
19327                tr = recentTaskForIdLocked(mTaskId);
19328                if (tr == null) {
19329                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19330                }
19331                if (tr.getRootActivity() != null) {
19332                    moveTaskToFrontLocked(tr.taskId, 0, null);
19333                    return;
19334                }
19335            }
19336
19337            startActivityFromRecentsInner(tr.taskId, null);
19338        }
19339
19340        @Override
19341        public int startActivity(IBinder whoThread, String callingPackage,
19342                Intent intent, String resolvedType, Bundle options) {
19343            checkCaller();
19344
19345            int callingUser = UserHandle.getCallingUserId();
19346            TaskRecord tr;
19347            IApplicationThread appThread;
19348            synchronized (ActivityManagerService.this) {
19349                tr = recentTaskForIdLocked(mTaskId);
19350                if (tr == null) {
19351                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19352                }
19353                appThread = ApplicationThreadNative.asInterface(whoThread);
19354                if (appThread == null) {
19355                    throw new IllegalArgumentException("Bad app thread " + appThread);
19356                }
19357            }
19358            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19359                    resolvedType, null, null, null, null, 0, 0, null, null,
19360                    null, options, callingUser, null, tr);
19361        }
19362
19363        @Override
19364        public void setExcludeFromRecents(boolean exclude) {
19365            checkCaller();
19366
19367            synchronized (ActivityManagerService.this) {
19368                long origId = Binder.clearCallingIdentity();
19369                try {
19370                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19371                    if (tr == null) {
19372                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19373                    }
19374                    Intent intent = tr.getBaseIntent();
19375                    if (exclude) {
19376                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19377                    } else {
19378                        intent.setFlags(intent.getFlags()
19379                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19380                    }
19381                } finally {
19382                    Binder.restoreCallingIdentity(origId);
19383                }
19384            }
19385        }
19386    }
19387}
19388