ActivityManagerService.java revision 71e737c8e8b970d780b930ebc6eacb4464d4a6aa
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                synchronized (ActivityManagerService.this) {
1673                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1674                }
1675                break;
1676            }
1677            case START_PROFILES_MSG: {
1678                synchronized (ActivityManagerService.this) {
1679                    startProfilesLocked();
1680                }
1681                break;
1682            }
1683            case UPDATE_TIME: {
1684                synchronized (ActivityManagerService.this) {
1685                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1686                        ProcessRecord r = mLruProcesses.get(i);
1687                        if (r.thread != null) {
1688                            try {
1689                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1690                            } catch (RemoteException ex) {
1691                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1692                            }
1693                        }
1694                    }
1695                }
1696                break;
1697            }
1698            case SYSTEM_USER_START_MSG: {
1699                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1700                        Integer.toString(msg.arg1), msg.arg1);
1701                mSystemServiceManager.startUser(msg.arg1);
1702                break;
1703            }
1704            case SYSTEM_USER_CURRENT_MSG: {
1705                mBatteryStatsService.noteEvent(
1706                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1707                        Integer.toString(msg.arg2), msg.arg2);
1708                mBatteryStatsService.noteEvent(
1709                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.switchUser(msg.arg1);
1712                break;
1713            }
1714            case ENTER_ANIMATION_COMPLETE_MSG: {
1715                synchronized (ActivityManagerService.this) {
1716                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1717                    if (r != null && r.app != null && r.app.thread != null) {
1718                        try {
1719                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1720                        } catch (RemoteException e) {
1721                        }
1722                    }
1723                }
1724                break;
1725            }
1726            case FINISH_BOOTING_MSG: {
1727                if (msg.arg1 != 0) {
1728                    finishBooting();
1729                }
1730                if (msg.arg2 != 0) {
1731                    enableScreenAfterBoot();
1732                }
1733                break;
1734            }
1735            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1736                try {
1737                    Locale l = (Locale) msg.obj;
1738                    IBinder service = ServiceManager.getService("mount");
1739                    IMountService mountService = IMountService.Stub.asInterface(service);
1740                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1741                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1742                } catch (RemoteException e) {
1743                    Log.e(TAG, "Error storing locale for decryption UI", e);
1744                }
1745                break;
1746            }
1747            case DISMISS_DIALOG_MSG: {
1748                final Dialog d = (Dialog) msg.obj;
1749                d.dismiss();
1750                break;
1751            }
1752            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1753                synchronized (ActivityManagerService.this) {
1754                    int i = mTaskStackListeners.beginBroadcast();
1755                    while (i > 0) {
1756                        i--;
1757                        try {
1758                            // Make a one-way callback to the listener
1759                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1760                        } catch (RemoteException e){
1761                            // Handled by the RemoteCallbackList
1762                        }
1763                    }
1764                    mTaskStackListeners.finishBroadcast();
1765                }
1766                break;
1767            }
1768            }
1769        }
1770    };
1771
1772    static final int COLLECT_PSS_BG_MSG = 1;
1773
1774    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1775        @Override
1776        public void handleMessage(Message msg) {
1777            switch (msg.what) {
1778            case COLLECT_PSS_BG_MSG: {
1779                long start = SystemClock.uptimeMillis();
1780                MemInfoReader memInfo = null;
1781                synchronized (ActivityManagerService.this) {
1782                    if (mFullPssPending) {
1783                        mFullPssPending = false;
1784                        memInfo = new MemInfoReader();
1785                    }
1786                }
1787                if (memInfo != null) {
1788                    updateCpuStatsNow();
1789                    long nativeTotalPss = 0;
1790                    synchronized (mProcessCpuTracker) {
1791                        final int N = mProcessCpuTracker.countStats();
1792                        for (int j=0; j<N; j++) {
1793                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1794                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1795                                // This is definitely an application process; skip it.
1796                                continue;
1797                            }
1798                            synchronized (mPidsSelfLocked) {
1799                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1800                                    // This is one of our own processes; skip it.
1801                                    continue;
1802                                }
1803                            }
1804                            nativeTotalPss += Debug.getPss(st.pid, null);
1805                        }
1806                    }
1807                    memInfo.readMemInfo();
1808                    synchronized (ActivityManagerService.this) {
1809                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1810                                + (SystemClock.uptimeMillis()-start) + "ms");
1811                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1812                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1813                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1814                    }
1815                }
1816
1817                int i = 0;
1818                int num = 0;
1819                long[] tmp = new long[1];
1820                do {
1821                    ProcessRecord proc;
1822                    int procState;
1823                    int pid;
1824                    synchronized (ActivityManagerService.this) {
1825                        if (i >= mPendingPssProcesses.size()) {
1826                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1827                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1828                            mPendingPssProcesses.clear();
1829                            return;
1830                        }
1831                        proc = mPendingPssProcesses.get(i);
1832                        procState = proc.pssProcState;
1833                        if (proc.thread != null && procState == proc.setProcState) {
1834                            pid = proc.pid;
1835                        } else {
1836                            proc = null;
1837                            pid = 0;
1838                        }
1839                        i++;
1840                    }
1841                    if (proc != null) {
1842                        long pss = Debug.getPss(pid, tmp);
1843                        synchronized (ActivityManagerService.this) {
1844                            if (proc.thread != null && proc.setProcState == procState
1845                                    && proc.pid == pid) {
1846                                num++;
1847                                proc.lastPssTime = SystemClock.uptimeMillis();
1848                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1849                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1850                                        + ": " + pss + " lastPss=" + proc.lastPss
1851                                        + " state=" + ProcessList.makeProcStateString(procState));
1852                                if (proc.initialIdlePss == 0) {
1853                                    proc.initialIdlePss = pss;
1854                                }
1855                                proc.lastPss = pss;
1856                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1857                                    proc.lastCachedPss = pss;
1858                                }
1859                            }
1860                        }
1861                    }
1862                } while (true);
1863            }
1864            }
1865        }
1866    };
1867
1868    public void setSystemProcess() {
1869        try {
1870            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1871            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1872            ServiceManager.addService("meminfo", new MemBinder(this));
1873            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1874            ServiceManager.addService("dbinfo", new DbBinder(this));
1875            if (MONITOR_CPU_USAGE) {
1876                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1877            }
1878            ServiceManager.addService("permission", new PermissionController(this));
1879
1880            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1881                    "android", STOCK_PM_FLAGS);
1882            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1883
1884            synchronized (this) {
1885                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1886                app.persistent = true;
1887                app.pid = MY_PID;
1888                app.maxAdj = ProcessList.SYSTEM_ADJ;
1889                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1890                mProcessNames.put(app.processName, app.uid, app);
1891                synchronized (mPidsSelfLocked) {
1892                    mPidsSelfLocked.put(app.pid, app);
1893                }
1894                updateLruProcessLocked(app, false, null);
1895                updateOomAdjLocked();
1896            }
1897        } catch (PackageManager.NameNotFoundException e) {
1898            throw new RuntimeException(
1899                    "Unable to find android system package", e);
1900        }
1901    }
1902
1903    public void setWindowManager(WindowManagerService wm) {
1904        mWindowManager = wm;
1905        mStackSupervisor.setWindowManager(wm);
1906    }
1907
1908    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1909        mUsageStatsService = usageStatsManager;
1910    }
1911
1912    public void startObservingNativeCrashes() {
1913        final NativeCrashListener ncl = new NativeCrashListener(this);
1914        ncl.start();
1915    }
1916
1917    public IAppOpsService getAppOpsService() {
1918        return mAppOpsService;
1919    }
1920
1921    static class MemBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        MemBinder(ActivityManagerService activityManagerService) {
1924            mActivityManagerService = activityManagerService;
1925        }
1926
1927        @Override
1928        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1929            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1930                    != PackageManager.PERMISSION_GRANTED) {
1931                pw.println("Permission Denial: can't dump meminfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1938        }
1939    }
1940
1941    static class GraphicsBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        GraphicsBinder(ActivityManagerService activityManagerService) {
1944            mActivityManagerService = activityManagerService;
1945        }
1946
1947        @Override
1948        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1949            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1950                    != PackageManager.PERMISSION_GRANTED) {
1951                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1958        }
1959    }
1960
1961    static class DbBinder extends Binder {
1962        ActivityManagerService mActivityManagerService;
1963        DbBinder(ActivityManagerService activityManagerService) {
1964            mActivityManagerService = activityManagerService;
1965        }
1966
1967        @Override
1968        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1970                    != PackageManager.PERMISSION_GRANTED) {
1971                pw.println("Permission Denial: can't dump dbinfo from from pid="
1972                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1973                        + " without permission " + android.Manifest.permission.DUMP);
1974                return;
1975            }
1976
1977            mActivityManagerService.dumpDbInfo(fd, pw, args);
1978        }
1979    }
1980
1981    static class CpuBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        CpuBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            synchronized (mActivityManagerService.mProcessCpuTracker) {
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2000                        SystemClock.uptimeMillis()));
2001            }
2002        }
2003    }
2004
2005    public static final class Lifecycle extends SystemService {
2006        private final ActivityManagerService mService;
2007
2008        public Lifecycle(Context context) {
2009            super(context);
2010            mService = new ActivityManagerService(context);
2011        }
2012
2013        @Override
2014        public void onStart() {
2015            mService.start();
2016        }
2017
2018        public ActivityManagerService getService() {
2019            return mService;
2020        }
2021    }
2022
2023    // Note: This method is invoked on the main thread but may need to attach various
2024    // handlers to other threads.  So take care to be explicit about the looper.
2025    public ActivityManagerService(Context systemContext) {
2026        mContext = systemContext;
2027        mFactoryTest = FactoryTest.getMode();
2028        mSystemThread = ActivityThread.currentActivityThread();
2029
2030        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2031
2032        mHandlerThread = new ServiceThread(TAG,
2033                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2034        mHandlerThread.start();
2035        mHandler = new MainHandler(mHandlerThread.getLooper());
2036
2037        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "foreground", BROADCAST_FG_TIMEOUT, false);
2039        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "background", BROADCAST_BG_TIMEOUT, true);
2041        mBroadcastQueues[0] = mFgBroadcastQueue;
2042        mBroadcastQueues[1] = mBgBroadcastQueue;
2043
2044        mServices = new ActiveServices(this);
2045        mProviderMap = new ProviderMap(this);
2046
2047        // TODO: Move creation of battery stats service outside of activity manager service.
2048        File dataDir = Environment.getDataDirectory();
2049        File systemDir = new File(dataDir, "system");
2050        systemDir.mkdirs();
2051        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2052        mBatteryStatsService.getActiveStatistics().readLocked();
2053        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2054        mOnBattery = DEBUG_POWER ? true
2055                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2056        mBatteryStatsService.getActiveStatistics().setCallback(this);
2057
2058        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2059
2060        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2061
2062        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2063
2064        // User 0 is the first and only user that runs at boot.
2065        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2066        mUserLru.add(Integer.valueOf(0));
2067        updateStartedUserArrayLocked();
2068
2069        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2070            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2071
2072        mConfiguration.setToDefaults();
2073        mConfiguration.setLocale(Locale.getDefault());
2074
2075        mConfigurationSeq = mConfiguration.seq = 1;
2076        mProcessCpuTracker.init();
2077
2078        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2079        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2080        mStackSupervisor = new ActivityStackSupervisor(this);
2081        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2082
2083        mProcessCpuThread = new Thread("CpuTracker") {
2084            @Override
2085            public void run() {
2086                while (true) {
2087                    try {
2088                        try {
2089                            synchronized(this) {
2090                                final long now = SystemClock.uptimeMillis();
2091                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2092                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2093                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2094                                //        + ", write delay=" + nextWriteDelay);
2095                                if (nextWriteDelay < nextCpuDelay) {
2096                                    nextCpuDelay = nextWriteDelay;
2097                                }
2098                                if (nextCpuDelay > 0) {
2099                                    mProcessCpuMutexFree.set(true);
2100                                    this.wait(nextCpuDelay);
2101                                }
2102                            }
2103                        } catch (InterruptedException e) {
2104                        }
2105                        updateCpuStatsNow();
2106                    } catch (Exception e) {
2107                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2108                    }
2109                }
2110            }
2111        };
2112
2113        Watchdog.getInstance().addMonitor(this);
2114        Watchdog.getInstance().addThread(mHandler);
2115    }
2116
2117    public void setSystemServiceManager(SystemServiceManager mgr) {
2118        mSystemServiceManager = mgr;
2119    }
2120
2121    public void setInstaller(Installer installer) {
2122        mInstaller = installer;
2123    }
2124
2125    private void start() {
2126        Process.removeAllProcessGroups();
2127        mProcessCpuThread.start();
2128
2129        mBatteryStatsService.publish(mContext);
2130        mAppOpsService.publish(mContext);
2131        Slog.d("AppOps", "AppOpsService published");
2132        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2133    }
2134
2135    public void initPowerManagement() {
2136        mStackSupervisor.initPowerManagement();
2137        mBatteryStatsService.initPowerManagement();
2138    }
2139
2140    @Override
2141    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2142            throws RemoteException {
2143        if (code == SYSPROPS_TRANSACTION) {
2144            // We need to tell all apps about the system property change.
2145            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2146            synchronized(this) {
2147                final int NP = mProcessNames.getMap().size();
2148                for (int ip=0; ip<NP; ip++) {
2149                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2150                    final int NA = apps.size();
2151                    for (int ia=0; ia<NA; ia++) {
2152                        ProcessRecord app = apps.valueAt(ia);
2153                        if (app.thread != null) {
2154                            procs.add(app.thread.asBinder());
2155                        }
2156                    }
2157                }
2158            }
2159
2160            int N = procs.size();
2161            for (int i=0; i<N; i++) {
2162                Parcel data2 = Parcel.obtain();
2163                try {
2164                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2165                } catch (RemoteException e) {
2166                }
2167                data2.recycle();
2168            }
2169        }
2170        try {
2171            return super.onTransact(code, data, reply, flags);
2172        } catch (RuntimeException e) {
2173            // The activity manager only throws security exceptions, so let's
2174            // log all others.
2175            if (!(e instanceof SecurityException)) {
2176                Slog.wtf(TAG, "Activity Manager Crash", e);
2177            }
2178            throw e;
2179        }
2180    }
2181
2182    void updateCpuStats() {
2183        final long now = SystemClock.uptimeMillis();
2184        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2185            return;
2186        }
2187        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2188            synchronized (mProcessCpuThread) {
2189                mProcessCpuThread.notify();
2190            }
2191        }
2192    }
2193
2194    void updateCpuStatsNow() {
2195        synchronized (mProcessCpuTracker) {
2196            mProcessCpuMutexFree.set(false);
2197            final long now = SystemClock.uptimeMillis();
2198            boolean haveNewCpuStats = false;
2199
2200            if (MONITOR_CPU_USAGE &&
2201                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2202                mLastCpuTime.set(now);
2203                haveNewCpuStats = true;
2204                mProcessCpuTracker.update();
2205                //Slog.i(TAG, mProcessCpu.printCurrentState());
2206                //Slog.i(TAG, "Total CPU usage: "
2207                //        + mProcessCpu.getTotalCpuPercent() + "%");
2208
2209                // Slog the cpu usage if the property is set.
2210                if ("true".equals(SystemProperties.get("events.cpu"))) {
2211                    int user = mProcessCpuTracker.getLastUserTime();
2212                    int system = mProcessCpuTracker.getLastSystemTime();
2213                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2214                    int irq = mProcessCpuTracker.getLastIrqTime();
2215                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2216                    int idle = mProcessCpuTracker.getLastIdleTime();
2217
2218                    int total = user + system + iowait + irq + softIrq + idle;
2219                    if (total == 0) total = 1;
2220
2221                    EventLog.writeEvent(EventLogTags.CPU,
2222                            ((user+system+iowait+irq+softIrq) * 100) / total,
2223                            (user * 100) / total,
2224                            (system * 100) / total,
2225                            (iowait * 100) / total,
2226                            (irq * 100) / total,
2227                            (softIrq * 100) / total);
2228                }
2229            }
2230
2231            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2232            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2233            synchronized(bstats) {
2234                synchronized(mPidsSelfLocked) {
2235                    if (haveNewCpuStats) {
2236                        if (mOnBattery) {
2237                            int perc = bstats.startAddingCpuLocked();
2238                            int totalUTime = 0;
2239                            int totalSTime = 0;
2240                            final int N = mProcessCpuTracker.countStats();
2241                            for (int i=0; i<N; i++) {
2242                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2243                                if (!st.working) {
2244                                    continue;
2245                                }
2246                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2247                                int otherUTime = (st.rel_utime*perc)/100;
2248                                int otherSTime = (st.rel_stime*perc)/100;
2249                                totalUTime += otherUTime;
2250                                totalSTime += otherSTime;
2251                                if (pr != null) {
2252                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2253                                    if (ps == null || !ps.isActive()) {
2254                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2255                                                pr.info.uid, pr.processName);
2256                                    }
2257                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2258                                            st.rel_stime-otherSTime);
2259                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2260                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2261                                } else {
2262                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2263                                    if (ps == null || !ps.isActive()) {
2264                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2265                                                bstats.mapUid(st.uid), st.name);
2266                                    }
2267                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2268                                            st.rel_stime-otherSTime);
2269                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2270                                }
2271                            }
2272                            bstats.finishAddingCpuLocked(perc, totalUTime,
2273                                    totalSTime, cpuSpeedTimes);
2274                        }
2275                    }
2276                }
2277
2278                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2279                    mLastWriteTime = now;
2280                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2281                }
2282            }
2283        }
2284    }
2285
2286    @Override
2287    public void batteryNeedsCpuUpdate() {
2288        updateCpuStatsNow();
2289    }
2290
2291    @Override
2292    public void batteryPowerChanged(boolean onBattery) {
2293        // When plugging in, update the CPU stats first before changing
2294        // the plug state.
2295        updateCpuStatsNow();
2296        synchronized (this) {
2297            synchronized(mPidsSelfLocked) {
2298                mOnBattery = DEBUG_POWER ? true : onBattery;
2299            }
2300        }
2301    }
2302
2303    /**
2304     * Initialize the application bind args. These are passed to each
2305     * process when the bindApplication() IPC is sent to the process. They're
2306     * lazily setup to make sure the services are running when they're asked for.
2307     */
2308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2309        if (mAppBindArgs == null) {
2310            mAppBindArgs = new HashMap<>();
2311
2312            // Isolated processes won't get this optimization, so that we don't
2313            // violate the rules about which services they have access to.
2314            if (!isolated) {
2315                // Setup the application init args
2316                mAppBindArgs.put("package", ServiceManager.getService("package"));
2317                mAppBindArgs.put("window", ServiceManager.getService("window"));
2318                mAppBindArgs.put(Context.ALARM_SERVICE,
2319                        ServiceManager.getService(Context.ALARM_SERVICE));
2320            }
2321        }
2322        return mAppBindArgs;
2323    }
2324
2325    final void setFocusedActivityLocked(ActivityRecord r) {
2326        if (mFocusedActivity != r) {
2327            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2328            mFocusedActivity = r;
2329            if (r.task != null && r.task.voiceInteractor != null) {
2330                startRunningVoiceLocked();
2331            } else {
2332                finishRunningVoiceLocked();
2333            }
2334            mStackSupervisor.setFocusedStack(r);
2335            if (r != null) {
2336                mWindowManager.setFocusedApp(r.appToken, true);
2337            }
2338            applyUpdateLockStateLocked(r);
2339        }
2340    }
2341
2342    final void clearFocusedActivity(ActivityRecord r) {
2343        if (mFocusedActivity == r) {
2344            mFocusedActivity = null;
2345        }
2346    }
2347
2348    @Override
2349    public void setFocusedStack(int stackId) {
2350        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2351        synchronized (ActivityManagerService.this) {
2352            ActivityStack stack = mStackSupervisor.getStack(stackId);
2353            if (stack != null) {
2354                ActivityRecord r = stack.topRunningActivityLocked(null);
2355                if (r != null) {
2356                    setFocusedActivityLocked(r);
2357                }
2358            }
2359        }
2360    }
2361
2362    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2363    @Override
2364    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2365        synchronized (ActivityManagerService.this) {
2366            if (listener != null) {
2367                mTaskStackListeners.register(listener);
2368            }
2369        }
2370    }
2371
2372    @Override
2373    public void notifyActivityDrawn(IBinder token) {
2374        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2375        synchronized (this) {
2376            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2377            if (r != null) {
2378                r.task.stack.notifyActivityDrawnLocked(r);
2379            }
2380        }
2381    }
2382
2383    final void applyUpdateLockStateLocked(ActivityRecord r) {
2384        // Modifications to the UpdateLock state are done on our handler, outside
2385        // the activity manager's locks.  The new state is determined based on the
2386        // state *now* of the relevant activity record.  The object is passed to
2387        // the handler solely for logging detail, not to be consulted/modified.
2388        final boolean nextState = r != null && r.immersive;
2389        mHandler.sendMessage(
2390                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2391    }
2392
2393    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2394        Message msg = Message.obtain();
2395        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2396        msg.obj = r.task.askedCompatMode ? null : r;
2397        mHandler.sendMessage(msg);
2398    }
2399
2400    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2401            String what, Object obj, ProcessRecord srcApp) {
2402        app.lastActivityTime = now;
2403
2404        if (app.activities.size() > 0) {
2405            // Don't want to touch dependent processes that are hosting activities.
2406            return index;
2407        }
2408
2409        int lrui = mLruProcesses.lastIndexOf(app);
2410        if (lrui < 0) {
2411            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2412                    + what + " " + obj + " from " + srcApp);
2413            return index;
2414        }
2415
2416        if (lrui >= index) {
2417            // Don't want to cause this to move dependent processes *back* in the
2418            // list as if they were less frequently used.
2419            return index;
2420        }
2421
2422        if (lrui >= mLruProcessActivityStart) {
2423            // Don't want to touch dependent processes that are hosting activities.
2424            return index;
2425        }
2426
2427        mLruProcesses.remove(lrui);
2428        if (index > 0) {
2429            index--;
2430        }
2431        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2432                + " in LRU list: " + app);
2433        mLruProcesses.add(index, app);
2434        return index;
2435    }
2436
2437    final void removeLruProcessLocked(ProcessRecord app) {
2438        int lrui = mLruProcesses.lastIndexOf(app);
2439        if (lrui >= 0) {
2440            if (!app.killed) {
2441                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2442                Process.killProcessQuiet(app.pid);
2443                Process.killProcessGroup(app.info.uid, app.pid);
2444            }
2445            if (lrui <= mLruProcessActivityStart) {
2446                mLruProcessActivityStart--;
2447            }
2448            if (lrui <= mLruProcessServiceStart) {
2449                mLruProcessServiceStart--;
2450            }
2451            mLruProcesses.remove(lrui);
2452        }
2453    }
2454
2455    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2456            ProcessRecord client) {
2457        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2458                || app.treatLikeActivity;
2459        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2460        if (!activityChange && hasActivity) {
2461            // The process has activities, so we are only allowing activity-based adjustments
2462            // to move it.  It should be kept in the front of the list with other
2463            // processes that have activities, and we don't want those to change their
2464            // order except due to activity operations.
2465            return;
2466        }
2467
2468        mLruSeq++;
2469        final long now = SystemClock.uptimeMillis();
2470        app.lastActivityTime = now;
2471
2472        // First a quick reject: if the app is already at the position we will
2473        // put it, then there is nothing to do.
2474        if (hasActivity) {
2475            final int N = mLruProcesses.size();
2476            if (N > 0 && mLruProcesses.get(N-1) == app) {
2477                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2478                return;
2479            }
2480        } else {
2481            if (mLruProcessServiceStart > 0
2482                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2483                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2484                return;
2485            }
2486        }
2487
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489
2490        if (app.persistent && lrui >= 0) {
2491            // We don't care about the position of persistent processes, as long as
2492            // they are in the list.
2493            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2494            return;
2495        }
2496
2497        /* In progress: compute new position first, so we can avoid doing work
2498           if the process is not actually going to move.  Not yet working.
2499        int addIndex;
2500        int nextIndex;
2501        boolean inActivity = false, inService = false;
2502        if (hasActivity) {
2503            // Process has activities, put it at the very tipsy-top.
2504            addIndex = mLruProcesses.size();
2505            nextIndex = mLruProcessServiceStart;
2506            inActivity = true;
2507        } else if (hasService) {
2508            // Process has services, put it at the top of the service list.
2509            addIndex = mLruProcessActivityStart;
2510            nextIndex = mLruProcessServiceStart;
2511            inActivity = true;
2512            inService = true;
2513        } else  {
2514            // Process not otherwise of interest, it goes to the top of the non-service area.
2515            addIndex = mLruProcessServiceStart;
2516            if (client != null) {
2517                int clientIndex = mLruProcesses.lastIndexOf(client);
2518                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2519                        + app);
2520                if (clientIndex >= 0 && addIndex > clientIndex) {
2521                    addIndex = clientIndex;
2522                }
2523            }
2524            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2525        }
2526
2527        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2528                + mLruProcessActivityStart + "): " + app);
2529        */
2530
2531        if (lrui >= 0) {
2532            if (lrui < mLruProcessActivityStart) {
2533                mLruProcessActivityStart--;
2534            }
2535            if (lrui < mLruProcessServiceStart) {
2536                mLruProcessServiceStart--;
2537            }
2538            /*
2539            if (addIndex > lrui) {
2540                addIndex--;
2541            }
2542            if (nextIndex > lrui) {
2543                nextIndex--;
2544            }
2545            */
2546            mLruProcesses.remove(lrui);
2547        }
2548
2549        /*
2550        mLruProcesses.add(addIndex, app);
2551        if (inActivity) {
2552            mLruProcessActivityStart++;
2553        }
2554        if (inService) {
2555            mLruProcessActivityStart++;
2556        }
2557        */
2558
2559        int nextIndex;
2560        if (hasActivity) {
2561            final int N = mLruProcesses.size();
2562            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2563                // Process doesn't have activities, but has clients with
2564                // activities...  move it up, but one below the top (the top
2565                // should always have a real activity).
2566                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2567                mLruProcesses.add(N-1, app);
2568                // To keep it from spamming the LRU list (by making a bunch of clients),
2569                // we will push down any other entries owned by the app.
2570                final int uid = app.info.uid;
2571                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2572                    ProcessRecord subProc = mLruProcesses.get(i);
2573                    if (subProc.info.uid == uid) {
2574                        // We want to push this one down the list.  If the process after
2575                        // it is for the same uid, however, don't do so, because we don't
2576                        // want them internally to be re-ordered.
2577                        if (mLruProcesses.get(i-1).info.uid != uid) {
2578                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2579                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2580                            ProcessRecord tmp = mLruProcesses.get(i);
2581                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2582                            mLruProcesses.set(i-1, tmp);
2583                            i--;
2584                        }
2585                    } else {
2586                        // A gap, we can stop here.
2587                        break;
2588                    }
2589                }
2590            } else {
2591                // Process has activities, put it at the very tipsy-top.
2592                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2593                mLruProcesses.add(app);
2594            }
2595            nextIndex = mLruProcessServiceStart;
2596        } else if (hasService) {
2597            // Process has services, put it at the top of the service list.
2598            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2599            mLruProcesses.add(mLruProcessActivityStart, app);
2600            nextIndex = mLruProcessServiceStart;
2601            mLruProcessActivityStart++;
2602        } else  {
2603            // Process not otherwise of interest, it goes to the top of the non-service area.
2604            int index = mLruProcessServiceStart;
2605            if (client != null) {
2606                // If there is a client, don't allow the process to be moved up higher
2607                // in the list than that client.
2608                int clientIndex = mLruProcesses.lastIndexOf(client);
2609                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2610                        + " when updating " + app);
2611                if (clientIndex <= lrui) {
2612                    // Don't allow the client index restriction to push it down farther in the
2613                    // list than it already is.
2614                    clientIndex = lrui;
2615                }
2616                if (clientIndex >= 0 && index > clientIndex) {
2617                    index = clientIndex;
2618                }
2619            }
2620            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2621            mLruProcesses.add(index, app);
2622            nextIndex = index-1;
2623            mLruProcessActivityStart++;
2624            mLruProcessServiceStart++;
2625        }
2626
2627        // If the app is currently using a content provider or service,
2628        // bump those processes as well.
2629        for (int j=app.connections.size()-1; j>=0; j--) {
2630            ConnectionRecord cr = app.connections.valueAt(j);
2631            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2632                    && cr.binding.service.app != null
2633                    && cr.binding.service.app.lruSeq != mLruSeq
2634                    && !cr.binding.service.app.persistent) {
2635                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2636                        "service connection", cr, app);
2637            }
2638        }
2639        for (int j=app.conProviders.size()-1; j>=0; j--) {
2640            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2641            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2642                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2643                        "provider reference", cpr, app);
2644            }
2645        }
2646    }
2647
2648    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2649        if (uid == Process.SYSTEM_UID) {
2650            // The system gets to run in any process.  If there are multiple
2651            // processes with the same uid, just pick the first (this
2652            // should never happen).
2653            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2654            if (procs == null) return null;
2655            final int N = procs.size();
2656            for (int i = 0; i < N; i++) {
2657                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2658            }
2659        }
2660        ProcessRecord proc = mProcessNames.get(processName, uid);
2661        if (false && proc != null && !keepIfLarge
2662                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2663                && proc.lastCachedPss >= 4000) {
2664            // Turn this condition on to cause killing to happen regularly, for testing.
2665            if (proc.baseProcessTracker != null) {
2666                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2667            }
2668            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2669        } else if (proc != null && !keepIfLarge
2670                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2672            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2673            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2674                if (proc.baseProcessTracker != null) {
2675                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676                }
2677                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2678            }
2679        }
2680        return proc;
2681    }
2682
2683    void ensurePackageDexOpt(String packageName) {
2684        IPackageManager pm = AppGlobals.getPackageManager();
2685        try {
2686            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2687                mDidDexOpt = true;
2688            }
2689        } catch (RemoteException e) {
2690        }
2691    }
2692
2693    boolean isNextTransitionForward() {
2694        int transit = mWindowManager.getPendingAppTransition();
2695        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2698    }
2699
2700    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2701            String processName, String abiOverride, int uid, Runnable crashHandler) {
2702        synchronized(this) {
2703            ApplicationInfo info = new ApplicationInfo();
2704            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2705            // For isolated processes, the former contains the parent's uid and the latter the
2706            // actual uid of the isolated process.
2707            // In the special case introduced by this method (which is, starting an isolated
2708            // process directly from the SystemServer without an actual parent app process) the
2709            // closest thing to a parent's uid is SYSTEM_UID.
2710            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2711            // the |isolated| logic in the ProcessRecord constructor.
2712            info.uid = Process.SYSTEM_UID;
2713            info.processName = processName;
2714            info.className = entryPoint;
2715            info.packageName = "android";
2716            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2717                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2718                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2719                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2720                    crashHandler);
2721            return proc != null ? proc.pid : 0;
2722        }
2723    }
2724
2725    final ProcessRecord startProcessLocked(String processName,
2726            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2727            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2728            boolean isolated, boolean keepIfLarge) {
2729        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2730                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2731                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2732                null /* crashHandler */);
2733    }
2734
2735    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2736            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2737            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2738            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2739        long startTime = SystemClock.elapsedRealtime();
2740        ProcessRecord app;
2741        if (!isolated) {
2742            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2743            checkTime(startTime, "startProcess: after getProcessRecord");
2744        } else {
2745            // If this is an isolated process, it can't re-use an existing process.
2746            app = null;
2747        }
2748        // We don't have to do anything more if:
2749        // (1) There is an existing application record; and
2750        // (2) The caller doesn't think it is dead, OR there is no thread
2751        //     object attached to it so we know it couldn't have crashed; and
2752        // (3) There is a pid assigned to it, so it is either starting or
2753        //     already running.
2754        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2755                + " app=" + app + " knownToBeDead=" + knownToBeDead
2756                + " thread=" + (app != null ? app.thread : null)
2757                + " pid=" + (app != null ? app.pid : -1));
2758        if (app != null && app.pid > 0) {
2759            if (!knownToBeDead || app.thread == null) {
2760                // We already have the app running, or are waiting for it to
2761                // come up (we have a pid but not yet its thread), so keep it.
2762                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2763                // If this is a new package in the process, add the package to the list
2764                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2765                checkTime(startTime, "startProcess: done, added package to proc");
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            checkTime(startTime, "startProcess: bad proc running, killing");
2773            Process.killProcessGroup(app.info.uid, app.pid);
2774            handleAppDiedLocked(app, true, true);
2775            checkTime(startTime, "startProcess: done killing old proc");
2776        }
2777
2778        String hostingNameStr = hostingName != null
2779                ? hostingName.flattenToShortString() : null;
2780
2781        if (!isolated) {
2782            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2783                // If we are in the background, then check to see if this process
2784                // is bad.  If so, we will just silently fail.
2785                if (mBadProcesses.get(info.processName, info.uid) != null) {
2786                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2787                            + "/" + info.processName);
2788                    return null;
2789                }
2790            } else {
2791                // When the user is explicitly starting a process, then clear its
2792                // crash count so that we won't make it bad until they see at
2793                // least one crash dialog again, and make the process good again
2794                // if it had been bad.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2796                        + "/" + info.processName);
2797                mProcessCrashTimes.remove(info.processName, info.uid);
2798                if (mBadProcesses.get(info.processName, info.uid) != null) {
2799                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2800                            UserHandle.getUserId(info.uid), info.uid,
2801                            info.processName);
2802                    mBadProcesses.remove(info.processName, info.uid);
2803                    if (app != null) {
2804                        app.bad = false;
2805                    }
2806                }
2807            }
2808        }
2809
2810        if (app == null) {
2811            checkTime(startTime, "startProcess: creating new process record");
2812            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2813            app.crashHandler = crashHandler;
2814            if (app == null) {
2815                Slog.w(TAG, "Failed making new process record for "
2816                        + processName + "/" + info.uid + " isolated=" + isolated);
2817                return null;
2818            }
2819            mProcessNames.put(processName, app.uid, app);
2820            if (isolated) {
2821                mIsolatedProcesses.put(app.uid, app);
2822            }
2823            checkTime(startTime, "startProcess: done creating new process record");
2824        } else {
2825            // If this is a new package in the process, add the package to the list
2826            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2827            checkTime(startTime, "startProcess: added package to existing proc");
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            checkTime(startTime, "startProcess: returning with proc on hold");
2840            return app;
2841        }
2842
2843        checkTime(startTime, "startProcess: stepping in to startProcess");
2844        startProcessLocked(
2845                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2846        checkTime(startTime, "startProcess: done starting proc!");
2847        return (app.pid != 0) ? app : null;
2848    }
2849
2850    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2851        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2852    }
2853
2854    private final void startProcessLocked(ProcessRecord app,
2855            String hostingType, String hostingNameStr) {
2856        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2857                null /* entryPoint */, null /* entryPointArgs */);
2858    }
2859
2860    private final void startProcessLocked(ProcessRecord app, String hostingType,
2861            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2862        long startTime = SystemClock.elapsedRealtime();
2863        if (app.pid > 0 && app.pid != MY_PID) {
2864            checkTime(startTime, "startProcess: removing from pids map");
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            checkTime(startTime, "startProcess: done removing from pids map");
2870            app.setPid(0);
2871        }
2872
2873        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2874                "startProcessLocked removing on hold: " + app);
2875        mProcessesOnHold.remove(app);
2876
2877        checkTime(startTime, "startProcess: starting to update cpu stats");
2878        updateCpuStats();
2879        checkTime(startTime, "startProcess: done updating cpu stats");
2880
2881        try {
2882            int uid = app.uid;
2883
2884            int[] gids = null;
2885            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2886            if (!app.isolated) {
2887                int[] permGids = null;
2888                try {
2889                    checkTime(startTime, "startProcess: getting gids from package manager");
2890                    final PackageManager pm = mContext.getPackageManager();
2891                    permGids = pm.getPackageGids(app.info.packageName);
2892
2893                    if (Environment.isExternalStorageEmulated()) {
2894                        checkTime(startTime, "startProcess: checking external storage perm");
2895                        if (pm.checkPermission(
2896                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2897                                app.info.packageName) == PERMISSION_GRANTED) {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2899                        } else {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2901                        }
2902                    }
2903                } catch (PackageManager.NameNotFoundException e) {
2904                    Slog.w(TAG, "Unable to retrieve gids", e);
2905                }
2906
2907                /*
2908                 * Add shared application and profile GIDs so applications can share some
2909                 * resources like shared libraries and access user-wide resources
2910                 */
2911                if (permGids == null) {
2912                    gids = new int[2];
2913                } else {
2914                    gids = new int[permGids.length + 2];
2915                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2916                }
2917                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2918                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2919            }
2920            checkTime(startTime, "startProcess: building args");
2921            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2922                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2923                        && mTopComponent != null
2924                        && app.processName.equals(mTopComponent.getPackageName())) {
2925                    uid = 0;
2926                }
2927                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2928                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2929                    uid = 0;
2930                }
2931            }
2932            int debugFlags = 0;
2933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2935                // Also turn on CheckJNI for debuggable apps. It's quite
2936                // awkward to turn on otherwise.
2937                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2938            }
2939            // Run the app in safe mode if its manifest requests so or the
2940            // system is booted in safe mode.
2941            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2942                mSafeMode == true) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2947            }
2948            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2949                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2950            }
2951            if ("1".equals(SystemProperties.get("debug.assert"))) {
2952                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2953            }
2954
2955            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2956            if (requiredAbi == null) {
2957                requiredAbi = Build.SUPPORTED_ABIS[0];
2958            }
2959
2960            String instructionSet = null;
2961            if (app.info.primaryCpuAbi != null) {
2962                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2963            }
2964
2965            // Start the process.  It will either succeed and return a result containing
2966            // the PID of the new process, or else throw a RuntimeException.
2967            boolean isActivityProcess = (entryPoint == null);
2968            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2969            checkTime(startTime, "startProcess: asking zygote to start proc");
2970            Process.ProcessStartResult startResult = Process.start(entryPoint,
2971                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2972                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2973                    app.info.dataDir, entryPointArgs);
2974            checkTime(startTime, "startProcess: returned from zygote!");
2975
2976            if (app.isolated) {
2977                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2978            }
2979            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2980            checkTime(startTime, "startProcess: done updating battery stats");
2981
2982            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2983                    UserHandle.getUserId(uid), startResult.pid, uid,
2984                    app.processName, hostingType,
2985                    hostingNameStr != null ? hostingNameStr : "");
2986
2987            if (app.persistent) {
2988                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2989            }
2990
2991            checkTime(startTime, "startProcess: building log message");
2992            StringBuilder buf = mStringBuilder;
2993            buf.setLength(0);
2994            buf.append("Start proc ");
2995            buf.append(app.processName);
2996            if (!isActivityProcess) {
2997                buf.append(" [");
2998                buf.append(entryPoint);
2999                buf.append("]");
3000            }
3001            buf.append(" for ");
3002            buf.append(hostingType);
3003            if (hostingNameStr != null) {
3004                buf.append(" ");
3005                buf.append(hostingNameStr);
3006            }
3007            buf.append(": pid=");
3008            buf.append(startResult.pid);
3009            buf.append(" uid=");
3010            buf.append(uid);
3011            buf.append(" gids={");
3012            if (gids != null) {
3013                for (int gi=0; gi<gids.length; gi++) {
3014                    if (gi != 0) buf.append(", ");
3015                    buf.append(gids[gi]);
3016
3017                }
3018            }
3019            buf.append("}");
3020            if (requiredAbi != null) {
3021                buf.append(" abi=");
3022                buf.append(requiredAbi);
3023            }
3024            Slog.i(TAG, buf.toString());
3025            app.setPid(startResult.pid);
3026            app.usingWrapper = startResult.usingWrapper;
3027            app.removed = false;
3028            app.killed = false;
3029            app.killedByAm = false;
3030            checkTime(startTime, "startProcess: starting to update pids map");
3031            synchronized (mPidsSelfLocked) {
3032                this.mPidsSelfLocked.put(startResult.pid, app);
3033                if (isActivityProcess) {
3034                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3035                    msg.obj = app;
3036                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3037                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3038                }
3039            }
3040            checkTime(startTime, "startProcess: done updating pids map");
3041        } catch (RuntimeException e) {
3042            // XXX do better error recovery.
3043            app.setPid(0);
3044            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3045            if (app.isolated) {
3046                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3047            }
3048            Slog.e(TAG, "Failure starting process " + app.processName, e);
3049        }
3050    }
3051
3052    void updateUsageStats(ActivityRecord component, boolean resumed) {
3053        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3054        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3055        if (resumed) {
3056            if (mUsageStatsService != null) {
3057                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3058                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3059            }
3060            synchronized (stats) {
3061                stats.noteActivityResumedLocked(component.app.uid);
3062            }
3063        } else {
3064            if (mUsageStatsService != null) {
3065                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3066                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3067            }
3068            synchronized (stats) {
3069                stats.noteActivityPausedLocked(component.app.uid);
3070            }
3071        }
3072    }
3073
3074    Intent getHomeIntent() {
3075        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3076        intent.setComponent(mTopComponent);
3077        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3078            intent.addCategory(Intent.CATEGORY_HOME);
3079        }
3080        return intent;
3081    }
3082
3083    boolean startHomeActivityLocked(int userId) {
3084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3085                && mTopAction == null) {
3086            // We are running in factory test mode, but unable to find
3087            // the factory test app, so just sit around displaying the
3088            // error message and don't try to start anything.
3089            return false;
3090        }
3091        Intent intent = getHomeIntent();
3092        ActivityInfo aInfo =
3093            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3094        if (aInfo != null) {
3095            intent.setComponent(new ComponentName(
3096                    aInfo.applicationInfo.packageName, aInfo.name));
3097            // Don't do this if the home app is currently being
3098            // instrumented.
3099            aInfo = new ActivityInfo(aInfo);
3100            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3101            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3102                    aInfo.applicationInfo.uid, true);
3103            if (app == null || app.instrumentationClass == null) {
3104                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3105                mStackSupervisor.startHomeActivity(intent, aInfo);
3106            }
3107        }
3108
3109        return true;
3110    }
3111
3112    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3113        ActivityInfo ai = null;
3114        ComponentName comp = intent.getComponent();
3115        try {
3116            if (comp != null) {
3117                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3118            } else {
3119                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3120                        intent,
3121                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3122                            flags, userId);
3123
3124                if (info != null) {
3125                    ai = info.activityInfo;
3126                }
3127            }
3128        } catch (RemoteException e) {
3129            // ignore
3130        }
3131
3132        return ai;
3133    }
3134
3135    /**
3136     * Starts the "new version setup screen" if appropriate.
3137     */
3138    void startSetupActivityLocked() {
3139        // Only do this once per boot.
3140        if (mCheckedForSetup) {
3141            return;
3142        }
3143
3144        // We will show this screen if the current one is a different
3145        // version than the last one shown, and we are not running in
3146        // low-level factory test mode.
3147        final ContentResolver resolver = mContext.getContentResolver();
3148        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3149                Settings.Global.getInt(resolver,
3150                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3151            mCheckedForSetup = true;
3152
3153            // See if we should be showing the platform update setup UI.
3154            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3155            List<ResolveInfo> ris = mContext.getPackageManager()
3156                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3157
3158            // We don't allow third party apps to replace this.
3159            ResolveInfo ri = null;
3160            for (int i=0; ris != null && i<ris.size(); i++) {
3161                if ((ris.get(i).activityInfo.applicationInfo.flags
3162                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3163                    ri = ris.get(i);
3164                    break;
3165                }
3166            }
3167
3168            if (ri != null) {
3169                String vers = ri.activityInfo.metaData != null
3170                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3171                        : null;
3172                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3173                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3174                            Intent.METADATA_SETUP_VERSION);
3175                }
3176                String lastVers = Settings.Secure.getString(
3177                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3178                if (vers != null && !vers.equals(lastVers)) {
3179                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3180                    intent.setComponent(new ComponentName(
3181                            ri.activityInfo.packageName, ri.activityInfo.name));
3182                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3183                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3184                            null);
3185                }
3186            }
3187        }
3188    }
3189
3190    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3191        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3192    }
3193
3194    void enforceNotIsolatedCaller(String caller) {
3195        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3196            throw new SecurityException("Isolated process not allowed to call " + caller);
3197        }
3198    }
3199
3200    void enforceShellRestriction(String restriction, int userHandle) {
3201        if (Binder.getCallingUid() == Process.SHELL_UID) {
3202            if (userHandle < 0
3203                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3204                throw new SecurityException("Shell does not have permission to access user "
3205                        + userHandle);
3206            }
3207        }
3208    }
3209
3210    @Override
3211    public int getFrontActivityScreenCompatMode() {
3212        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3213        synchronized (this) {
3214            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3215        }
3216    }
3217
3218    @Override
3219    public void setFrontActivityScreenCompatMode(int mode) {
3220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3221                "setFrontActivityScreenCompatMode");
3222        synchronized (this) {
3223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3224        }
3225    }
3226
3227    @Override
3228    public int getPackageScreenCompatMode(String packageName) {
3229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3232        }
3233    }
3234
3235    @Override
3236    public void setPackageScreenCompatMode(String packageName, int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setPackageScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3241        }
3242    }
3243
3244    @Override
3245    public boolean getPackageAskScreenCompat(String packageName) {
3246        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageAskScreenCompat");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3258        }
3259    }
3260
3261    private void dispatchProcessesChanged() {
3262        int N;
3263        synchronized (this) {
3264            N = mPendingProcessChanges.size();
3265            if (mActiveProcessChanges.length < N) {
3266                mActiveProcessChanges = new ProcessChangeItem[N];
3267            }
3268            mPendingProcessChanges.toArray(mActiveProcessChanges);
3269            mAvailProcessChanges.addAll(mPendingProcessChanges);
3270            mPendingProcessChanges.clear();
3271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3272        }
3273
3274        int i = mProcessObservers.beginBroadcast();
3275        while (i > 0) {
3276            i--;
3277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3278            if (observer != null) {
3279                try {
3280                    for (int j=0; j<N; j++) {
3281                        ProcessChangeItem item = mActiveProcessChanges[j];
3282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3284                                    + item.pid + " uid=" + item.uid + ": "
3285                                    + item.foregroundActivities);
3286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3287                                    item.foregroundActivities);
3288                        }
3289                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3292                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3293                        }
3294                    }
3295                } catch (RemoteException e) {
3296                }
3297            }
3298        }
3299        mProcessObservers.finishBroadcast();
3300    }
3301
3302    private void dispatchProcessDied(int pid, int uid) {
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    observer.onProcessDied(pid, uid);
3310                } catch (RemoteException e) {
3311                }
3312            }
3313        }
3314        mProcessObservers.finishBroadcast();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3320            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3321        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3322            resultWho, requestCode, startFlags, profilerInfo, options,
3323            UserHandle.getCallingUserId());
3324    }
3325
3326    @Override
3327    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3329            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3330        enforceNotIsolatedCaller("startActivity");
3331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3332                false, ALLOW_FULL_ONLY, "startActivity", null);
3333        // TODO: Switch to user app stacks here.
3334        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3336                profilerInfo, null, null, options, userId, null, null);
3337    }
3338
3339    @Override
3340    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3342            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3343
3344        // This is very dangerous -- it allows you to perform a start activity (including
3345        // permission grants) as any app that may launch one of your own activities.  So
3346        // we will only allow this to be done from activities that are part of the core framework,
3347        // and then only when they are running as the system.
3348        final ActivityRecord sourceRecord;
3349        final int targetUid;
3350        final String targetPackage;
3351        synchronized (this) {
3352            if (resultTo == null) {
3353                throw new SecurityException("Must be called from an activity");
3354            }
3355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3356            if (sourceRecord == null) {
3357                throw new SecurityException("Called with bad activity token: " + resultTo);
3358            }
3359            if (!sourceRecord.info.packageName.equals("android")) {
3360                throw new SecurityException(
3361                        "Must be called from an activity that is declared in the android package");
3362            }
3363            if (sourceRecord.app == null) {
3364                throw new SecurityException("Called without a process attached to activity");
3365            }
3366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3367                // This is still okay, as long as this activity is running under the
3368                // uid of the original calling activity.
3369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3370                    throw new SecurityException(
3371                            "Calling activity in uid " + sourceRecord.app.uid
3372                                    + " must be system uid or original calling uid "
3373                                    + sourceRecord.launchedFromUid);
3374                }
3375            }
3376            targetUid = sourceRecord.launchedFromUid;
3377            targetPackage = sourceRecord.launchedFromPackage;
3378        }
3379
3380        if (userId == UserHandle.USER_NULL) {
3381            userId = UserHandle.getUserId(sourceRecord.app.uid);
3382        }
3383
3384        // TODO: Switch to user app stacks here.
3385        try {
3386            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3387                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3388                    null, null, options, userId, null, null);
3389            return ret;
3390        } catch (SecurityException e) {
3391            // XXX need to figure out how to propagate to original app.
3392            // A SecurityException here is generally actually a fault of the original
3393            // calling activity (such as a fairly granting permissions), so propagate it
3394            // back to them.
3395            /*
3396            StringBuilder msg = new StringBuilder();
3397            msg.append("While launching");
3398            msg.append(intent.toString());
3399            msg.append(": ");
3400            msg.append(e.getMessage());
3401            */
3402            throw e;
3403        }
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3409            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3410        enforceNotIsolatedCaller("startActivityAndWait");
3411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3412                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3413        WaitResult res = new WaitResult();
3414        // TODO: Switch to user app stacks here.
3415        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3416                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3417                options, userId, null, null);
3418        return res;
3419    }
3420
3421    @Override
3422    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3423            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3424            int startFlags, Configuration config, Bundle options, int userId) {
3425        enforceNotIsolatedCaller("startActivityWithConfig");
3426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3427                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3428        // TODO: Switch to user app stacks here.
3429        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3430                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3431                null, null, config, options, userId, null, null);
3432        return ret;
3433    }
3434
3435    @Override
3436    public int startActivityIntentSender(IApplicationThread caller,
3437            IntentSender intent, Intent fillInIntent, String resolvedType,
3438            IBinder resultTo, String resultWho, int requestCode,
3439            int flagsMask, int flagsValues, Bundle options) {
3440        enforceNotIsolatedCaller("startActivityIntentSender");
3441        // Refuse possible leaked file descriptors
3442        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        IIntentSender sender = intent.getTarget();
3447        if (!(sender instanceof PendingIntentRecord)) {
3448            throw new IllegalArgumentException("Bad PendingIntent object");
3449        }
3450
3451        PendingIntentRecord pir = (PendingIntentRecord)sender;
3452
3453        synchronized (this) {
3454            // If this is coming from the currently resumed activity, it is
3455            // effectively saying that app switches are allowed at this point.
3456            final ActivityStack stack = getFocusedStack();
3457            if (stack.mResumedActivity != null &&
3458                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3459                mAppSwitchesAllowedTime = 0;
3460            }
3461        }
3462        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3463                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3469            Intent intent, String resolvedType, IVoiceInteractionSession session,
3470            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3471            Bundle options, int userId) {
3472        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3473                != PackageManager.PERMISSION_GRANTED) {
3474            String msg = "Permission Denial: startVoiceActivity() from pid="
3475                    + Binder.getCallingPid()
3476                    + ", uid=" + Binder.getCallingUid()
3477                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3478            Slog.w(TAG, msg);
3479            throw new SecurityException(msg);
3480        }
3481        if (session == null || interactor == null) {
3482            throw new NullPointerException("null session or interactor");
3483        }
3484        userId = handleIncomingUser(callingPid, callingUid, userId,
3485                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3486        // TODO: Switch to user app stacks here.
3487        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3488                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3489                null, options, userId, null, null);
3490    }
3491
3492    @Override
3493    public boolean startNextMatchingActivity(IBinder callingActivity,
3494            Intent intent, Bundle options) {
3495        // Refuse possible leaked file descriptors
3496        if (intent != null && intent.hasFileDescriptors() == true) {
3497            throw new IllegalArgumentException("File descriptors passed in Intent");
3498        }
3499
3500        synchronized (this) {
3501            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3502            if (r == null) {
3503                ActivityOptions.abort(options);
3504                return false;
3505            }
3506            if (r.app == null || r.app.thread == null) {
3507                // The caller is not running...  d'oh!
3508                ActivityOptions.abort(options);
3509                return false;
3510            }
3511            intent = new Intent(intent);
3512            // The caller is not allowed to change the data.
3513            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3514            // And we are resetting to find the next component...
3515            intent.setComponent(null);
3516
3517            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3518
3519            ActivityInfo aInfo = null;
3520            try {
3521                List<ResolveInfo> resolves =
3522                    AppGlobals.getPackageManager().queryIntentActivities(
3523                            intent, r.resolvedType,
3524                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3525                            UserHandle.getCallingUserId());
3526
3527                // Look for the original activity in the list...
3528                final int N = resolves != null ? resolves.size() : 0;
3529                for (int i=0; i<N; i++) {
3530                    ResolveInfo rInfo = resolves.get(i);
3531                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3532                            && rInfo.activityInfo.name.equals(r.info.name)) {
3533                        // We found the current one...  the next matching is
3534                        // after it.
3535                        i++;
3536                        if (i<N) {
3537                            aInfo = resolves.get(i).activityInfo;
3538                        }
3539                        if (debug) {
3540                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3541                                    + "/" + r.info.name);
3542                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3543                                    + "/" + aInfo.name);
3544                        }
3545                        break;
3546                    }
3547                }
3548            } catch (RemoteException e) {
3549            }
3550
3551            if (aInfo == null) {
3552                // Nobody who is next!
3553                ActivityOptions.abort(options);
3554                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3555                return false;
3556            }
3557
3558            intent.setComponent(new ComponentName(
3559                    aInfo.applicationInfo.packageName, aInfo.name));
3560            intent.setFlags(intent.getFlags()&~(
3561                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3562                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3563                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3564                    Intent.FLAG_ACTIVITY_NEW_TASK));
3565
3566            // Okay now we need to start the new activity, replacing the
3567            // currently running activity.  This is a little tricky because
3568            // we want to start the new one as if the current one is finished,
3569            // but not finish the current one first so that there is no flicker.
3570            // And thus...
3571            final boolean wasFinishing = r.finishing;
3572            r.finishing = true;
3573
3574            // Propagate reply information over to the new activity.
3575            final ActivityRecord resultTo = r.resultTo;
3576            final String resultWho = r.resultWho;
3577            final int requestCode = r.requestCode;
3578            r.resultTo = null;
3579            if (resultTo != null) {
3580                resultTo.removeResultsLocked(r, resultWho, requestCode);
3581            }
3582
3583            final long origId = Binder.clearCallingIdentity();
3584            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3585                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3586                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3587                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3588            Binder.restoreCallingIdentity(origId);
3589
3590            r.finishing = wasFinishing;
3591            if (res != ActivityManager.START_SUCCESS) {
3592                return false;
3593            }
3594            return true;
3595        }
3596    }
3597
3598    @Override
3599    public final int startActivityFromRecents(int taskId, Bundle options) {
3600        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3601            String msg = "Permission Denial: startActivityFromRecents called without " +
3602                    START_TASKS_FROM_RECENTS;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        return startActivityFromRecentsInner(taskId, options);
3607    }
3608
3609    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3610        final TaskRecord task;
3611        final int callingUid;
3612        final String callingPackage;
3613        final Intent intent;
3614        final int userId;
3615        synchronized (this) {
3616            task = recentTaskForIdLocked(taskId);
3617            if (task == null) {
3618                throw new IllegalArgumentException("Task " + taskId + " not found.");
3619            }
3620            callingUid = task.mCallingUid;
3621            callingPackage = task.mCallingPackage;
3622            intent = task.intent;
3623            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3624            userId = task.userId;
3625        }
3626        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3627                options, userId, null, task);
3628    }
3629
3630    final int startActivityInPackage(int uid, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo,
3632            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3633            IActivityContainer container, TaskRecord inTask) {
3634
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3637
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, null, options, userId, container, inTask);
3642        return ret;
3643    }
3644
3645    @Override
3646    public final int startActivities(IApplicationThread caller, String callingPackage,
3647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3648            int userId) {
3649        enforceNotIsolatedCaller("startActivities");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivity", null);
3652        // TODO: Switch to user app stacks here.
3653        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3654                resolvedTypes, resultTo, options, userId);
3655        return ret;
3656    }
3657
3658    final int startActivitiesInPackage(int uid, String callingPackage,
3659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3660            Bundle options, int userId) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3666                resultTo, options, userId);
3667        return ret;
3668    }
3669
3670    //explicitly remove thd old information in mRecentTasks when removing existing user.
3671    private void removeRecentTasksForUserLocked(int userId) {
3672        if(userId <= 0) {
3673            Slog.i(TAG, "Can't remove recent task on user " + userId);
3674            return;
3675        }
3676
3677        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3678            TaskRecord tr = mRecentTasks.get(i);
3679            if (tr.userId == userId) {
3680                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3681                        + " when finishing user" + userId);
3682                mRecentTasks.remove(i);
3683                tr.removedFromRecents();
3684            }
3685        }
3686
3687        // Remove tasks from persistent storage.
3688        notifyTaskPersisterLocked(null, true);
3689    }
3690
3691    // Sort by taskId
3692    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3693        @Override
3694        public int compare(TaskRecord lhs, TaskRecord rhs) {
3695            return rhs.taskId - lhs.taskId;
3696        }
3697    };
3698
3699    // Extract the affiliates of the chain containing mRecentTasks[start].
3700    private int processNextAffiliateChainLocked(int start) {
3701        final TaskRecord startTask = mRecentTasks.get(start);
3702        final int affiliateId = startTask.mAffiliatedTaskId;
3703
3704        // Quick identification of isolated tasks. I.e. those not launched behind.
3705        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3706                startTask.mNextAffiliate == null) {
3707            // There is still a slim chance that there are other tasks that point to this task
3708            // and that the chain is so messed up that this task no longer points to them but
3709            // the gain of this optimization outweighs the risk.
3710            startTask.inRecents = true;
3711            return start + 1;
3712        }
3713
3714        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3715        mTmpRecents.clear();
3716        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3717            final TaskRecord task = mRecentTasks.get(i);
3718            if (task.mAffiliatedTaskId == affiliateId) {
3719                mRecentTasks.remove(i);
3720                mTmpRecents.add(task);
3721            }
3722        }
3723
3724        // Sort them all by taskId. That is the order they were create in and that order will
3725        // always be correct.
3726        Collections.sort(mTmpRecents, mTaskRecordComparator);
3727
3728        // Go through and fix up the linked list.
3729        // The first one is the end of the chain and has no next.
3730        final TaskRecord first = mTmpRecents.get(0);
3731        first.inRecents = true;
3732        if (first.mNextAffiliate != null) {
3733            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3734            first.setNextAffiliate(null);
3735            notifyTaskPersisterLocked(first, false);
3736        }
3737        // Everything in the middle is doubly linked from next to prev.
3738        final int tmpSize = mTmpRecents.size();
3739        for (int i = 0; i < tmpSize - 1; ++i) {
3740            final TaskRecord next = mTmpRecents.get(i);
3741            final TaskRecord prev = mTmpRecents.get(i + 1);
3742            if (next.mPrevAffiliate != prev) {
3743                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3744                        " setting prev=" + prev);
3745                next.setPrevAffiliate(prev);
3746                notifyTaskPersisterLocked(next, false);
3747            }
3748            if (prev.mNextAffiliate != next) {
3749                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3750                        " setting next=" + next);
3751                prev.setNextAffiliate(next);
3752                notifyTaskPersisterLocked(prev, false);
3753            }
3754            prev.inRecents = true;
3755        }
3756        // The last one is the beginning of the list and has no prev.
3757        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3758        if (last.mPrevAffiliate != null) {
3759            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3760            last.setPrevAffiliate(null);
3761            notifyTaskPersisterLocked(last, false);
3762        }
3763
3764        // Insert the group back into mRecentTasks at start.
3765        mRecentTasks.addAll(start, mTmpRecents);
3766
3767        // Let the caller know where we left off.
3768        return start + tmpSize;
3769    }
3770
3771    /**
3772     * Update the recent tasks lists: make sure tasks should still be here (their
3773     * applications / activities still exist), update their availability, fixup ordering
3774     * of affiliations.
3775     */
3776    void cleanupRecentTasksLocked(int userId) {
3777        if (mRecentTasks == null) {
3778            // Happens when called from the packagemanager broadcast before boot.
3779            return;
3780        }
3781
3782        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3783        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3784        final IPackageManager pm = AppGlobals.getPackageManager();
3785        final ActivityInfo dummyAct = new ActivityInfo();
3786        final ApplicationInfo dummyApp = new ApplicationInfo();
3787
3788        int N = mRecentTasks.size();
3789
3790        int[] users = userId == UserHandle.USER_ALL
3791                ? getUsersLocked() : new int[] { userId };
3792        for (int user : users) {
3793            for (int i = 0; i < N; i++) {
3794                TaskRecord task = mRecentTasks.get(i);
3795                if (task.userId != user) {
3796                    // Only look at tasks for the user ID of interest.
3797                    continue;
3798                }
3799                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3800                    // This situation is broken, and we should just get rid of it now.
3801                    mRecentTasks.remove(i);
3802                    task.removedFromRecents();
3803                    i--;
3804                    N--;
3805                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3806                    continue;
3807                }
3808                // Check whether this activity is currently available.
3809                if (task.realActivity != null) {
3810                    ActivityInfo ai = availActCache.get(task.realActivity);
3811                    if (ai == null) {
3812                        try {
3813                            ai = pm.getActivityInfo(task.realActivity,
3814                                    PackageManager.GET_UNINSTALLED_PACKAGES
3815                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3816                        } catch (RemoteException e) {
3817                            // Will never happen.
3818                            continue;
3819                        }
3820                        if (ai == null) {
3821                            ai = dummyAct;
3822                        }
3823                        availActCache.put(task.realActivity, ai);
3824                    }
3825                    if (ai == dummyAct) {
3826                        // This could be either because the activity no longer exists, or the
3827                        // app is temporarily gone.  For the former we want to remove the recents
3828                        // entry; for the latter we want to mark it as unavailable.
3829                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3830                        if (app == null) {
3831                            try {
3832                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3833                                        PackageManager.GET_UNINSTALLED_PACKAGES
3834                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3835                            } catch (RemoteException e) {
3836                                // Will never happen.
3837                                continue;
3838                            }
3839                            if (app == null) {
3840                                app = dummyApp;
3841                            }
3842                            availAppCache.put(task.realActivity.getPackageName(), app);
3843                        }
3844                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3845                            // Doesn't exist any more!  Good-bye.
3846                            mRecentTasks.remove(i);
3847                            task.removedFromRecents();
3848                            i--;
3849                            N--;
3850                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3851                            continue;
3852                        } else {
3853                            // Otherwise just not available for now.
3854                            if (task.isAvailable) {
3855                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3856                                        + task);
3857                            }
3858                            task.isAvailable = false;
3859                        }
3860                    } else {
3861                        if (!ai.enabled || !ai.applicationInfo.enabled
3862                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3863                            if (task.isAvailable) {
3864                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3865                                        + task + " (enabled=" + ai.enabled + "/"
3866                                        + ai.applicationInfo.enabled +  " flags="
3867                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3868                            }
3869                            task.isAvailable = false;
3870                        } else {
3871                            if (!task.isAvailable) {
3872                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3873                                        + task);
3874                            }
3875                            task.isAvailable = true;
3876                        }
3877                    }
3878                }
3879            }
3880        }
3881
3882        // Verify the affiliate chain for each task.
3883        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3884        }
3885
3886        mTmpRecents.clear();
3887        // mRecentTasks is now in sorted, affiliated order.
3888    }
3889
3890    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3891        int N = mRecentTasks.size();
3892        TaskRecord top = task;
3893        int topIndex = taskIndex;
3894        while (top.mNextAffiliate != null && topIndex > 0) {
3895            top = top.mNextAffiliate;
3896            topIndex--;
3897        }
3898        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3899                + topIndex + " from intial " + taskIndex);
3900        // Find the end of the chain, doing a sanity check along the way.
3901        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3902        int endIndex = topIndex;
3903        TaskRecord prev = top;
3904        while (endIndex < N) {
3905            TaskRecord cur = mRecentTasks.get(endIndex);
3906            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3907                    + endIndex + " " + cur);
3908            if (cur == top) {
3909                // Verify start of the chain.
3910                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3911                    Slog.wtf(TAG, "Bad chain @" + endIndex
3912                            + ": first task has next affiliate: " + prev);
3913                    sane = false;
3914                    break;
3915                }
3916            } else {
3917                // Verify middle of the chain's next points back to the one before.
3918                if (cur.mNextAffiliate != prev
3919                        || cur.mNextAffiliateTaskId != prev.taskId) {
3920                    Slog.wtf(TAG, "Bad chain @" + endIndex
3921                            + ": middle task " + cur + " @" + endIndex
3922                            + " has bad next affiliate "
3923                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3924                            + ", expected " + prev);
3925                    sane = false;
3926                    break;
3927                }
3928            }
3929            if (cur.mPrevAffiliateTaskId == -1) {
3930                // Chain ends here.
3931                if (cur.mPrevAffiliate != null) {
3932                    Slog.wtf(TAG, "Bad chain @" + endIndex
3933                            + ": last task " + cur + " has previous affiliate "
3934                            + cur.mPrevAffiliate);
3935                    sane = false;
3936                }
3937                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3938                break;
3939            } else {
3940                // Verify middle of the chain's prev points to a valid item.
3941                if (cur.mPrevAffiliate == null) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": task " + cur + " has previous affiliate "
3944                            + cur.mPrevAffiliate + " but should be id "
3945                            + cur.mPrevAffiliate);
3946                    sane = false;
3947                    break;
3948                }
3949            }
3950            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3951                Slog.wtf(TAG, "Bad chain @" + endIndex
3952                        + ": task " + cur + " has affiliated id "
3953                        + cur.mAffiliatedTaskId + " but should be "
3954                        + task.mAffiliatedTaskId);
3955                sane = false;
3956                break;
3957            }
3958            prev = cur;
3959            endIndex++;
3960            if (endIndex >= N) {
3961                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3962                        + ": last task " + prev);
3963                sane = false;
3964                break;
3965            }
3966        }
3967        if (sane) {
3968            if (endIndex < taskIndex) {
3969                Slog.wtf(TAG, "Bad chain @" + endIndex
3970                        + ": did not extend to task " + task + " @" + taskIndex);
3971                sane = false;
3972            }
3973        }
3974        if (sane) {
3975            // All looks good, we can just move all of the affiliated tasks
3976            // to the top.
3977            for (int i=topIndex; i<=endIndex; i++) {
3978                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3979                        + " from " + i + " to " + (i-topIndex));
3980                TaskRecord cur = mRecentTasks.remove(i);
3981                mRecentTasks.add(i-topIndex, cur);
3982            }
3983            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3984                    + " to " + endIndex);
3985            return true;
3986        }
3987
3988        // Whoops, couldn't do it.
3989        return false;
3990    }
3991
3992    final void addRecentTaskLocked(TaskRecord task) {
3993        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3994                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3995
3996        int N = mRecentTasks.size();
3997        // Quick case: check if the top-most recent task is the same.
3998        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3999            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4000            return;
4001        }
4002        // Another quick case: check if this is part of a set of affiliated
4003        // tasks that are at the top.
4004        if (isAffiliated && N > 0 && task.inRecents
4005                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4006            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4007                    + " at top when adding " + task);
4008            return;
4009        }
4010        // Another quick case: never add voice sessions.
4011        if (task.voiceSession != null) {
4012            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4013            return;
4014        }
4015
4016        boolean needAffiliationFix = false;
4017
4018        // Slightly less quick case: the task is already in recents, so all we need
4019        // to do is move it.
4020        if (task.inRecents) {
4021            int taskIndex = mRecentTasks.indexOf(task);
4022            if (taskIndex >= 0) {
4023                if (!isAffiliated) {
4024                    // Simple case: this is not an affiliated task, so we just move it to the front.
4025                    mRecentTasks.remove(taskIndex);
4026                    mRecentTasks.add(0, task);
4027                    notifyTaskPersisterLocked(task, false);
4028                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4029                            + " from " + taskIndex);
4030                    return;
4031                } else {
4032                    // More complicated: need to keep all affiliated tasks together.
4033                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4034                        // All went well.
4035                        return;
4036                    }
4037
4038                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4039                    // everything and then go through our general path of adding a new task.
4040                    needAffiliationFix = true;
4041                }
4042            } else {
4043                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4044                needAffiliationFix = true;
4045            }
4046        }
4047
4048        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4049        trimRecentsForTaskLocked(task, true);
4050
4051        N = mRecentTasks.size();
4052        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4053            final TaskRecord tr = mRecentTasks.remove(N - 1);
4054            tr.removedFromRecents();
4055            N--;
4056        }
4057        task.inRecents = true;
4058        if (!isAffiliated || needAffiliationFix) {
4059            // If this is a simple non-affiliated task, or we had some failure trying to
4060            // handle it as part of an affilated task, then just place it at the top.
4061            mRecentTasks.add(0, task);
4062        } else if (isAffiliated) {
4063            // If this is a new affiliated task, then move all of the affiliated tasks
4064            // to the front and insert this new one.
4065            TaskRecord other = task.mNextAffiliate;
4066            if (other == null) {
4067                other = task.mPrevAffiliate;
4068            }
4069            if (other != null) {
4070                int otherIndex = mRecentTasks.indexOf(other);
4071                if (otherIndex >= 0) {
4072                    // Insert new task at appropriate location.
4073                    int taskIndex;
4074                    if (other == task.mNextAffiliate) {
4075                        // We found the index of our next affiliation, which is who is
4076                        // before us in the list, so add after that point.
4077                        taskIndex = otherIndex+1;
4078                    } else {
4079                        // We found the index of our previous affiliation, which is who is
4080                        // after us in the list, so add at their position.
4081                        taskIndex = otherIndex;
4082                    }
4083                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4084                            + taskIndex + ": " + task);
4085                    mRecentTasks.add(taskIndex, task);
4086
4087                    // Now move everything to the front.
4088                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4089                        // All went well.
4090                        return;
4091                    }
4092
4093                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4094                    // everything and then go through our general path of adding a new task.
4095                    needAffiliationFix = true;
4096                } else {
4097                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4098                            + other);
4099                    needAffiliationFix = true;
4100                }
4101            } else {
4102                if (DEBUG_RECENTS) Slog.d(TAG,
4103                        "addRecent: adding affiliated task without next/prev:" + task);
4104                needAffiliationFix = true;
4105            }
4106        }
4107        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4108
4109        if (needAffiliationFix) {
4110            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4111            cleanupRecentTasksLocked(task.userId);
4112        }
4113    }
4114
4115    /**
4116     * If needed, remove oldest existing entries in recents that are for the same kind
4117     * of task as the given one.
4118     */
4119    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4120        int N = mRecentTasks.size();
4121        final Intent intent = task.intent;
4122        final boolean document = intent != null && intent.isDocument();
4123
4124        int maxRecents = task.maxRecents - 1;
4125        for (int i=0; i<N; i++) {
4126            final TaskRecord tr = mRecentTasks.get(i);
4127            if (task != tr) {
4128                if (task.userId != tr.userId) {
4129                    continue;
4130                }
4131                if (i > MAX_RECENT_BITMAPS) {
4132                    tr.freeLastThumbnail();
4133                }
4134                final Intent trIntent = tr.intent;
4135                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4136                    (intent == null || !intent.filterEquals(trIntent))) {
4137                    continue;
4138                }
4139                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4140                if (document && trIsDocument) {
4141                    // These are the same document activity (not necessarily the same doc).
4142                    if (maxRecents > 0) {
4143                        --maxRecents;
4144                        continue;
4145                    }
4146                    // Hit the maximum number of documents for this task. Fall through
4147                    // and remove this document from recents.
4148                } else if (document || trIsDocument) {
4149                    // Only one of these is a document. Not the droid we're looking for.
4150                    continue;
4151                }
4152            }
4153
4154            if (!doTrim) {
4155                // If the caller is not actually asking for a trim, just tell them we reached
4156                // a point where the trim would happen.
4157                return i;
4158            }
4159
4160            // Either task and tr are the same or, their affinities match or their intents match
4161            // and neither of them is a document, or they are documents using the same activity
4162            // and their maxRecents has been reached.
4163            tr.disposeThumbnail();
4164            mRecentTasks.remove(i);
4165            if (task != tr) {
4166                tr.removedFromRecents();
4167            }
4168            i--;
4169            N--;
4170            if (task.intent == null) {
4171                // If the new recent task we are adding is not fully
4172                // specified, then replace it with the existing recent task.
4173                task = tr;
4174            }
4175            notifyTaskPersisterLocked(tr, false);
4176        }
4177
4178        return -1;
4179    }
4180
4181    @Override
4182    public void reportActivityFullyDrawn(IBinder token) {
4183        synchronized (this) {
4184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4185            if (r == null) {
4186                return;
4187            }
4188            r.reportFullyDrawnLocked();
4189        }
4190    }
4191
4192    @Override
4193    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4194        synchronized (this) {
4195            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4196            if (r == null) {
4197                return;
4198            }
4199            final long origId = Binder.clearCallingIdentity();
4200            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4201            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4202                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4203            if (config != null) {
4204                r.frozenBeforeDestroy = true;
4205                if (!updateConfigurationLocked(config, r, false, false)) {
4206                    mStackSupervisor.resumeTopActivitiesLocked();
4207                }
4208            }
4209            Binder.restoreCallingIdentity(origId);
4210        }
4211    }
4212
4213    @Override
4214    public int getRequestedOrientation(IBinder token) {
4215        synchronized (this) {
4216            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4217            if (r == null) {
4218                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4219            }
4220            return mWindowManager.getAppOrientation(r.appToken);
4221        }
4222    }
4223
4224    /**
4225     * This is the internal entry point for handling Activity.finish().
4226     *
4227     * @param token The Binder token referencing the Activity we want to finish.
4228     * @param resultCode Result code, if any, from this Activity.
4229     * @param resultData Result data (Intent), if any, from this Activity.
4230     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4231     *            the root Activity in the task.
4232     *
4233     * @return Returns true if the activity successfully finished, or false if it is still running.
4234     */
4235    @Override
4236    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4237            boolean finishTask) {
4238        // Refuse possible leaked file descriptors
4239        if (resultData != null && resultData.hasFileDescriptors() == true) {
4240            throw new IllegalArgumentException("File descriptors passed in Intent");
4241        }
4242
4243        synchronized(this) {
4244            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4245            if (r == null) {
4246                return true;
4247            }
4248            // Keep track of the root activity of the task before we finish it
4249            TaskRecord tr = r.task;
4250            ActivityRecord rootR = tr.getRootActivity();
4251            if (rootR == null) {
4252                Slog.w(TAG, "Finishing task with all activities already finished");
4253            }
4254            // Do not allow task to finish in Lock Task mode.
4255            if (tr == mStackSupervisor.mLockTaskModeTask) {
4256                if (rootR == r) {
4257                    Slog.i(TAG, "Not finishing task in lock task mode");
4258                    mStackSupervisor.showLockTaskToast();
4259                    return false;
4260                }
4261            }
4262            if (mController != null) {
4263                // Find the first activity that is not finishing.
4264                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4265                if (next != null) {
4266                    // ask watcher if this is allowed
4267                    boolean resumeOK = true;
4268                    try {
4269                        resumeOK = mController.activityResuming(next.packageName);
4270                    } catch (RemoteException e) {
4271                        mController = null;
4272                        Watchdog.getInstance().setActivityController(null);
4273                    }
4274
4275                    if (!resumeOK) {
4276                        Slog.i(TAG, "Not finishing activity because controller resumed");
4277                        return false;
4278                    }
4279                }
4280            }
4281            final long origId = Binder.clearCallingIdentity();
4282            try {
4283                boolean res;
4284                if (finishTask && r == rootR) {
4285                    // If requested, remove the task that is associated to this activity only if it
4286                    // was the root activity in the task. The result code and data is ignored
4287                    // because we don't support returning them across task boundaries.
4288                    res = removeTaskByIdLocked(tr.taskId, false);
4289                    if (!res) {
4290                        Slog.i(TAG, "Removing task failed to finish activity");
4291                    }
4292                } else {
4293                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4294                            resultData, "app-request", true);
4295                    if (!res) {
4296                        Slog.i(TAG, "Failed to finish by app-request");
4297                    }
4298                }
4299                return res;
4300            } finally {
4301                Binder.restoreCallingIdentity(origId);
4302            }
4303        }
4304    }
4305
4306    @Override
4307    public final void finishHeavyWeightApp() {
4308        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4309                != PackageManager.PERMISSION_GRANTED) {
4310            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4311                    + Binder.getCallingPid()
4312                    + ", uid=" + Binder.getCallingUid()
4313                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4314            Slog.w(TAG, msg);
4315            throw new SecurityException(msg);
4316        }
4317
4318        synchronized(this) {
4319            if (mHeavyWeightProcess == null) {
4320                return;
4321            }
4322
4323            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4324                    mHeavyWeightProcess.activities);
4325            for (int i=0; i<activities.size(); i++) {
4326                ActivityRecord r = activities.get(i);
4327                if (!r.finishing) {
4328                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4329                            null, "finish-heavy", true);
4330                }
4331            }
4332
4333            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4334                    mHeavyWeightProcess.userId, 0));
4335            mHeavyWeightProcess = null;
4336        }
4337    }
4338
4339    @Override
4340    public void crashApplication(int uid, int initialPid, String packageName,
4341            String message) {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: crashApplication() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351
4352        synchronized(this) {
4353            ProcessRecord proc = null;
4354
4355            // Figure out which process to kill.  We don't trust that initialPid
4356            // still has any relation to current pids, so must scan through the
4357            // list.
4358            synchronized (mPidsSelfLocked) {
4359                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4360                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4361                    if (p.uid != uid) {
4362                        continue;
4363                    }
4364                    if (p.pid == initialPid) {
4365                        proc = p;
4366                        break;
4367                    }
4368                    if (p.pkgList.containsKey(packageName)) {
4369                        proc = p;
4370                    }
4371                }
4372            }
4373
4374            if (proc == null) {
4375                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4376                        + " initialPid=" + initialPid
4377                        + " packageName=" + packageName);
4378                return;
4379            }
4380
4381            if (proc.thread != null) {
4382                if (proc.pid == Process.myPid()) {
4383                    Log.w(TAG, "crashApplication: trying to crash self!");
4384                    return;
4385                }
4386                long ident = Binder.clearCallingIdentity();
4387                try {
4388                    proc.thread.scheduleCrash(message);
4389                } catch (RemoteException e) {
4390                }
4391                Binder.restoreCallingIdentity(ident);
4392            }
4393        }
4394    }
4395
4396    @Override
4397    public final void finishSubActivity(IBinder token, String resultWho,
4398            int requestCode) {
4399        synchronized(this) {
4400            final long origId = Binder.clearCallingIdentity();
4401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4402            if (r != null) {
4403                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4404            }
4405            Binder.restoreCallingIdentity(origId);
4406        }
4407    }
4408
4409    @Override
4410    public boolean finishActivityAffinity(IBinder token) {
4411        synchronized(this) {
4412            final long origId = Binder.clearCallingIdentity();
4413            try {
4414                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4415
4416                ActivityRecord rootR = r.task.getRootActivity();
4417                // Do not allow task to finish in Lock Task mode.
4418                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4419                    if (rootR == r) {
4420                        mStackSupervisor.showLockTaskToast();
4421                        return false;
4422                    }
4423                }
4424                boolean res = false;
4425                if (r != null) {
4426                    res = r.task.stack.finishActivityAffinityLocked(r);
4427                }
4428                return res;
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void finishVoiceTask(IVoiceInteractionSession session) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                mStackSupervisor.finishVoiceTask(session);
4441            } finally {
4442                Binder.restoreCallingIdentity(origId);
4443            }
4444        }
4445
4446    }
4447
4448    @Override
4449    public boolean releaseActivityInstance(IBinder token) {
4450        synchronized(this) {
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                if (r.task == null || r.task.stack == null) {
4455                    return false;
4456                }
4457                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public void releaseSomeActivities(IApplicationThread appInt) {
4466        synchronized(this) {
4467            final long origId = Binder.clearCallingIdentity();
4468            try {
4469                ProcessRecord app = getRecordForAppLocked(appInt);
4470                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public boolean willActivityBeVisible(IBinder token) {
4479        synchronized(this) {
4480            ActivityStack stack = ActivityRecord.getStackLocked(token);
4481            if (stack != null) {
4482                return stack.willActivityBeVisibleLocked(token);
4483            }
4484            return false;
4485        }
4486    }
4487
4488    @Override
4489    public void overridePendingTransition(IBinder token, String packageName,
4490            int enterAnim, int exitAnim) {
4491        synchronized(this) {
4492            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493            if (self == null) {
4494                return;
4495            }
4496
4497            final long origId = Binder.clearCallingIdentity();
4498
4499            if (self.state == ActivityState.RESUMED
4500                    || self.state == ActivityState.PAUSING) {
4501                mWindowManager.overridePendingAppTransition(packageName,
4502                        enterAnim, exitAnim, null);
4503            }
4504
4505            Binder.restoreCallingIdentity(origId);
4506        }
4507    }
4508
4509    /**
4510     * Main function for removing an existing process from the activity manager
4511     * as a result of that process going away.  Clears out all connections
4512     * to the process.
4513     */
4514    private final void handleAppDiedLocked(ProcessRecord app,
4515            boolean restarting, boolean allowRestart) {
4516        int pid = app.pid;
4517        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518        if (!kept && !restarting) {
4519            removeLruProcessLocked(app);
4520            if (pid > 0) {
4521                ProcessList.remove(pid);
4522            }
4523        }
4524
4525        if (mProfileProc == app) {
4526            clearProfilerLocked();
4527        }
4528
4529        // Remove this application's activities from active lists.
4530        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532        app.activities.clear();
4533
4534        if (app.instrumentationClass != null) {
4535            Slog.w(TAG, "Crash of app " + app.processName
4536                  + " running instrumentation " + app.instrumentationClass);
4537            Bundle info = new Bundle();
4538            info.putString("shortMsg", "Process crashed.");
4539            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540        }
4541
4542        if (!restarting) {
4543            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4544                // If there was nothing to resume, and we are not already
4545                // restarting this process, but there is a visible activity that
4546                // is hosted by the process...  then make sure all visible
4547                // activities are running, taking care of restarting this
4548                // process.
4549                if (hasVisibleActivities) {
4550                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4551                }
4552            }
4553        }
4554    }
4555
4556    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4557        IBinder threadBinder = thread.asBinder();
4558        // Find the application record.
4559        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4560            ProcessRecord rec = mLruProcesses.get(i);
4561            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4562                return i;
4563            }
4564        }
4565        return -1;
4566    }
4567
4568    final ProcessRecord getRecordForAppLocked(
4569            IApplicationThread thread) {
4570        if (thread == null) {
4571            return null;
4572        }
4573
4574        int appIndex = getLRURecordIndexForAppLocked(thread);
4575        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4576    }
4577
4578    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4579        // If there are no longer any background processes running,
4580        // and the app that died was not running instrumentation,
4581        // then tell everyone we are now low on memory.
4582        boolean haveBg = false;
4583        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4584            ProcessRecord rec = mLruProcesses.get(i);
4585            if (rec.thread != null
4586                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4587                haveBg = true;
4588                break;
4589            }
4590        }
4591
4592        if (!haveBg) {
4593            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4594            if (doReport) {
4595                long now = SystemClock.uptimeMillis();
4596                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4597                    doReport = false;
4598                } else {
4599                    mLastMemUsageReportTime = now;
4600                }
4601            }
4602            final ArrayList<ProcessMemInfo> memInfos
4603                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4604            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4605            long now = SystemClock.uptimeMillis();
4606            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4607                ProcessRecord rec = mLruProcesses.get(i);
4608                if (rec == dyingProc || rec.thread == null) {
4609                    continue;
4610                }
4611                if (doReport) {
4612                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4613                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4614                }
4615                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4616                    // The low memory report is overriding any current
4617                    // state for a GC request.  Make sure to do
4618                    // heavy/important/visible/foreground processes first.
4619                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4620                        rec.lastRequestedGc = 0;
4621                    } else {
4622                        rec.lastRequestedGc = rec.lastLowMemory;
4623                    }
4624                    rec.reportLowMemory = true;
4625                    rec.lastLowMemory = now;
4626                    mProcessesToGc.remove(rec);
4627                    addProcessToGcListLocked(rec);
4628                }
4629            }
4630            if (doReport) {
4631                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4632                mHandler.sendMessage(msg);
4633            }
4634            scheduleAppGcsLocked();
4635        }
4636    }
4637
4638    final void appDiedLocked(ProcessRecord app) {
4639       appDiedLocked(app, app.pid, app.thread);
4640    }
4641
4642    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4643        // First check if this ProcessRecord is actually active for the pid.
4644        synchronized (mPidsSelfLocked) {
4645            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4646            if (curProc != app) {
4647                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4648                return;
4649            }
4650        }
4651
4652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4653        synchronized (stats) {
4654            stats.noteProcessDiedLocked(app.info.uid, pid);
4655        }
4656
4657        Process.killProcessQuiet(pid);
4658        Process.killProcessGroup(app.info.uid, pid);
4659        app.killed = true;
4660
4661        // Clean up already done if the process has been re-started.
4662        if (app.pid == pid && app.thread != null &&
4663                app.thread.asBinder() == thread.asBinder()) {
4664            boolean doLowMem = app.instrumentationClass == null;
4665            boolean doOomAdj = doLowMem;
4666            if (!app.killedByAm) {
4667                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4668                        + ") has died");
4669                mAllowLowerMemLevel = true;
4670            } else {
4671                // Note that we always want to do oom adj to update our state with the
4672                // new number of procs.
4673                mAllowLowerMemLevel = false;
4674                doLowMem = false;
4675            }
4676            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4677            if (DEBUG_CLEANUP) Slog.v(
4678                TAG, "Dying app: " + app + ", pid: " + pid
4679                + ", thread: " + thread.asBinder());
4680            handleAppDiedLocked(app, false, true);
4681
4682            if (doOomAdj) {
4683                updateOomAdjLocked();
4684            }
4685            if (doLowMem) {
4686                doLowMemReportIfNeededLocked(app);
4687            }
4688        } else if (app.pid != pid) {
4689            // A new process has already been started.
4690            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                    + ") has died and restarted (pid " + app.pid + ").");
4692            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693        } else if (DEBUG_PROCESSES) {
4694            Slog.d(TAG, "Received spurious death notification for thread "
4695                    + thread.asBinder());
4696        }
4697    }
4698
4699    /**
4700     * If a stack trace dump file is configured, dump process stack traces.
4701     * @param clearTraces causes the dump file to be erased prior to the new
4702     *    traces being written, if true; when false, the new traces will be
4703     *    appended to any existing file content.
4704     * @param firstPids of dalvik VM processes to dump stack traces for first
4705     * @param lastPids of dalvik VM processes to dump stack traces for last
4706     * @param nativeProcs optional list of native process names to dump stack crawls
4707     * @return file containing stack traces, or null if no dump file is configured
4708     */
4709    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712        if (tracesPath == null || tracesPath.length() == 0) {
4713            return null;
4714        }
4715
4716        File tracesFile = new File(tracesPath);
4717        try {
4718            File tracesDir = tracesFile.getParentFile();
4719            if (!tracesDir.exists()) {
4720                tracesDir.mkdirs();
4721                if (!SELinux.restorecon(tracesDir)) {
4722                    return null;
4723                }
4724            }
4725            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728            tracesFile.createNewFile();
4729            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730        } catch (IOException e) {
4731            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732            return null;
4733        }
4734
4735        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736        return tracesFile;
4737    }
4738
4739    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741        // Use a FileObserver to detect when traces finish writing.
4742        // The order of traces is considered important to maintain for legibility.
4743        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744            @Override
4745            public synchronized void onEvent(int event, String path) { notify(); }
4746        };
4747
4748        try {
4749            observer.startWatching();
4750
4751            // First collect all of the stacks of the most important pids.
4752            if (firstPids != null) {
4753                try {
4754                    int num = firstPids.size();
4755                    for (int i = 0; i < num; i++) {
4756                        synchronized (observer) {
4757                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                            observer.wait(200);  // Wait for write-close, give up after 200msec
4759                        }
4760                    }
4761                } catch (InterruptedException e) {
4762                    Slog.wtf(TAG, e);
4763                }
4764            }
4765
4766            // Next collect the stacks of the native pids
4767            if (nativeProcs != null) {
4768                int[] pids = Process.getPidsForCommands(nativeProcs);
4769                if (pids != null) {
4770                    for (int pid : pids) {
4771                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                    }
4773                }
4774            }
4775
4776            // Lastly, measure CPU usage.
4777            if (processCpuTracker != null) {
4778                processCpuTracker.init();
4779                System.gc();
4780                processCpuTracker.update();
4781                try {
4782                    synchronized (processCpuTracker) {
4783                        processCpuTracker.wait(500); // measure over 1/2 second.
4784                    }
4785                } catch (InterruptedException e) {
4786                }
4787                processCpuTracker.update();
4788
4789                // We'll take the stack crawls of just the top apps using CPU.
4790                final int N = processCpuTracker.countWorkingStats();
4791                int numProcs = 0;
4792                for (int i=0; i<N && numProcs<5; i++) {
4793                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                        numProcs++;
4796                        try {
4797                            synchronized (observer) {
4798                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                observer.wait(200);  // Wait for write-close, give up after 200msec
4800                            }
4801                        } catch (InterruptedException e) {
4802                            Slog.wtf(TAG, e);
4803                        }
4804
4805                    }
4806                }
4807            }
4808        } finally {
4809            observer.stopWatching();
4810        }
4811    }
4812
4813    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814        if (true || IS_USER_BUILD) {
4815            return;
4816        }
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return;
4820        }
4821
4822        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823        StrictMode.allowThreadDiskWrites();
4824        try {
4825            final File tracesFile = new File(tracesPath);
4826            final File tracesDir = tracesFile.getParentFile();
4827            final File tracesTmp = new File(tracesDir, "__tmp__");
4828            try {
4829                if (!tracesDir.exists()) {
4830                    tracesDir.mkdirs();
4831                    if (!SELinux.restorecon(tracesDir.getPath())) {
4832                        return;
4833                    }
4834                }
4835                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                if (tracesFile.exists()) {
4838                    tracesTmp.delete();
4839                    tracesFile.renameTo(tracesTmp);
4840                }
4841                StringBuilder sb = new StringBuilder();
4842                Time tobj = new Time();
4843                tobj.set(System.currentTimeMillis());
4844                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                sb.append(": ");
4846                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                sb.append(" since ");
4848                sb.append(msg);
4849                FileOutputStream fos = new FileOutputStream(tracesFile);
4850                fos.write(sb.toString().getBytes());
4851                if (app == null) {
4852                    fos.write("\n*** No application process!".getBytes());
4853                }
4854                fos.close();
4855                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856            } catch (IOException e) {
4857                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                return;
4859            }
4860
4861            if (app != null) {
4862                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                firstPids.add(app.pid);
4864                dumpStackTraces(tracesPath, firstPids, null, null, null);
4865            }
4866
4867            File lastTracesFile = null;
4868            File curTracesFile = null;
4869            for (int i=9; i>=0; i--) {
4870                String name = String.format(Locale.US, "slow%02d.txt", i);
4871                curTracesFile = new File(tracesDir, name);
4872                if (curTracesFile.exists()) {
4873                    if (lastTracesFile != null) {
4874                        curTracesFile.renameTo(lastTracesFile);
4875                    } else {
4876                        curTracesFile.delete();
4877                    }
4878                }
4879                lastTracesFile = curTracesFile;
4880            }
4881            tracesFile.renameTo(curTracesFile);
4882            if (tracesTmp.exists()) {
4883                tracesTmp.renameTo(tracesFile);
4884            }
4885        } finally {
4886            StrictMode.setThreadPolicy(oldPolicy);
4887        }
4888    }
4889
4890    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895        if (mController != null) {
4896            try {
4897                // 0 == continue, -1 = kill process immediately
4898                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                if (res < 0 && app.pid != MY_PID) {
4900                    app.kill("anr", true);
4901                }
4902            } catch (RemoteException e) {
4903                mController = null;
4904                Watchdog.getInstance().setActivityController(null);
4905            }
4906        }
4907
4908        long anrTime = SystemClock.uptimeMillis();
4909        if (MONITOR_CPU_USAGE) {
4910            updateCpuStatsNow();
4911        }
4912
4913        synchronized (this) {
4914            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915            if (mShuttingDown) {
4916                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                return;
4918            } else if (app.notResponding) {
4919                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.crashing) {
4922                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                return;
4924            }
4925
4926            // In case we come through here for the same app before completing
4927            // this one, mark as anring now so we will bail out.
4928            app.notResponding = true;
4929
4930            // Log the ANR to the event log.
4931            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                    app.processName, app.info.flags, annotation);
4933
4934            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935            firstPids.add(app.pid);
4936
4937            int parentPid = app.pid;
4938            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939            if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                ProcessRecord r = mLruProcesses.get(i);
4945                if (r != null && r.thread != null) {
4946                    int pid = r.pid;
4947                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                        if (r.persistent) {
4949                            firstPids.add(pid);
4950                        } else {
4951                            lastPids.put(pid, Boolean.TRUE);
4952                        }
4953                    }
4954                }
4955            }
4956        }
4957
4958        // Log the ANR to the main log.
4959        StringBuilder info = new StringBuilder();
4960        info.setLength(0);
4961        info.append("ANR in ").append(app.processName);
4962        if (activity != null && activity.shortComponentName != null) {
4963            info.append(" (").append(activity.shortComponentName).append(")");
4964        }
4965        info.append("\n");
4966        info.append("PID: ").append(app.pid).append("\n");
4967        if (annotation != null) {
4968            info.append("Reason: ").append(annotation).append("\n");
4969        }
4970        if (parent != null && parent != activity) {
4971            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972        }
4973
4974        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                NATIVE_STACKS_OF_INTEREST);
4978
4979        String cpuInfo = null;
4980        if (MONITOR_CPU_USAGE) {
4981            updateCpuStatsNow();
4982            synchronized (mProcessCpuTracker) {
4983                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984            }
4985            info.append(processCpuTracker.printCurrentLoad());
4986            info.append(cpuInfo);
4987        }
4988
4989        info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991        Slog.e(TAG, info.toString());
4992        if (tracesFile == null) {
4993            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995        }
4996
4997        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                cpuInfo, tracesFile, null);
4999
5000        if (mController != null) {
5001            try {
5002                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                if (res != 0) {
5005                    if (res < 0 && app.pid != MY_PID) {
5006                        app.kill("anr", true);
5007                    } else {
5008                        synchronized (this) {
5009                            mServices.scheduleServiceTimeoutLocked(app);
5010                        }
5011                    }
5012                    return;
5013                }
5014            } catch (RemoteException e) {
5015                mController = null;
5016                Watchdog.getInstance().setActivityController(null);
5017            }
5018        }
5019
5020        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024        synchronized (this) {
5025            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5026                app.kill("bg anr", true);
5027                return;
5028            }
5029
5030            // Set the app's notResponding state, and look up the errorReportReceiver
5031            makeAppNotRespondingLocked(app,
5032                    activity != null ? activity.shortComponentName : null,
5033                    annotation != null ? "ANR " + annotation : "ANR",
5034                    info.toString());
5035
5036            // Bring up the infamous App Not Responding dialog
5037            Message msg = Message.obtain();
5038            HashMap<String, Object> map = new HashMap<String, Object>();
5039            msg.what = SHOW_NOT_RESPONDING_MSG;
5040            msg.obj = map;
5041            msg.arg1 = aboveSystem ? 1 : 0;
5042            map.put("app", app);
5043            if (activity != null) {
5044                map.put("activity", activity);
5045            }
5046
5047            mHandler.sendMessage(msg);
5048        }
5049    }
5050
5051    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5052        if (!mLaunchWarningShown) {
5053            mLaunchWarningShown = true;
5054            mHandler.post(new Runnable() {
5055                @Override
5056                public void run() {
5057                    synchronized (ActivityManagerService.this) {
5058                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5059                        d.show();
5060                        mHandler.postDelayed(new Runnable() {
5061                            @Override
5062                            public void run() {
5063                                synchronized (ActivityManagerService.this) {
5064                                    d.dismiss();
5065                                    mLaunchWarningShown = false;
5066                                }
5067                            }
5068                        }, 4000);
5069                    }
5070                }
5071            });
5072        }
5073    }
5074
5075    @Override
5076    public boolean clearApplicationUserData(final String packageName,
5077            final IPackageDataObserver observer, int userId) {
5078        enforceNotIsolatedCaller("clearApplicationUserData");
5079        int uid = Binder.getCallingUid();
5080        int pid = Binder.getCallingPid();
5081        userId = handleIncomingUser(pid, uid,
5082                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5083        long callingId = Binder.clearCallingIdentity();
5084        try {
5085            IPackageManager pm = AppGlobals.getPackageManager();
5086            int pkgUid = -1;
5087            synchronized(this) {
5088                try {
5089                    pkgUid = pm.getPackageUid(packageName, userId);
5090                } catch (RemoteException e) {
5091                }
5092                if (pkgUid == -1) {
5093                    Slog.w(TAG, "Invalid packageName: " + packageName);
5094                    if (observer != null) {
5095                        try {
5096                            observer.onRemoveCompleted(packageName, false);
5097                        } catch (RemoteException e) {
5098                            Slog.i(TAG, "Observer no longer exists.");
5099                        }
5100                    }
5101                    return false;
5102                }
5103                if (uid == pkgUid || checkComponentPermission(
5104                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5105                        pid, uid, -1, true)
5106                        == PackageManager.PERMISSION_GRANTED) {
5107                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5108                } else {
5109                    throw new SecurityException("PID " + pid + " does not have permission "
5110                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5111                                    + " of package " + packageName);
5112                }
5113
5114                // Remove all tasks match the cleared application package and user
5115                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5116                    final TaskRecord tr = mRecentTasks.get(i);
5117                    final String taskPackageName =
5118                            tr.getBaseIntent().getComponent().getPackageName();
5119                    if (tr.userId != userId) continue;
5120                    if (!taskPackageName.equals(packageName)) continue;
5121                    removeTaskByIdLocked(tr.taskId, false);
5122                }
5123            }
5124
5125            try {
5126                // Clear application user data
5127                pm.clearApplicationUserData(packageName, observer, userId);
5128
5129                synchronized(this) {
5130                    // Remove all permissions granted from/to this package
5131                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5132                }
5133
5134                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5135                        Uri.fromParts("package", packageName, null));
5136                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5137                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5138                        null, null, 0, null, null, null, false, false, userId);
5139            } catch (RemoteException e) {
5140            }
5141        } finally {
5142            Binder.restoreCallingIdentity(callingId);
5143        }
5144        return true;
5145    }
5146
5147    @Override
5148    public void killBackgroundProcesses(final String packageName, int userId) {
5149        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5150                != PackageManager.PERMISSION_GRANTED &&
5151                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5152                        != PackageManager.PERMISSION_GRANTED) {
5153            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5154                    + Binder.getCallingPid()
5155                    + ", uid=" + Binder.getCallingUid()
5156                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5157            Slog.w(TAG, msg);
5158            throw new SecurityException(msg);
5159        }
5160
5161        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5162                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5163        long callingId = Binder.clearCallingIdentity();
5164        try {
5165            IPackageManager pm = AppGlobals.getPackageManager();
5166            synchronized(this) {
5167                int appId = -1;
5168                try {
5169                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5170                } catch (RemoteException e) {
5171                }
5172                if (appId == -1) {
5173                    Slog.w(TAG, "Invalid packageName: " + packageName);
5174                    return;
5175                }
5176                killPackageProcessesLocked(packageName, appId, userId,
5177                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182    }
5183
5184    @Override
5185    public void killAllBackgroundProcesses() {
5186        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5187                != PackageManager.PERMISSION_GRANTED) {
5188            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5189                    + Binder.getCallingPid()
5190                    + ", uid=" + Binder.getCallingUid()
5191                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5192            Slog.w(TAG, msg);
5193            throw new SecurityException(msg);
5194        }
5195
5196        long callingId = Binder.clearCallingIdentity();
5197        try {
5198            synchronized(this) {
5199                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5200                final int NP = mProcessNames.getMap().size();
5201                for (int ip=0; ip<NP; ip++) {
5202                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5203                    final int NA = apps.size();
5204                    for (int ia=0; ia<NA; ia++) {
5205                        ProcessRecord app = apps.valueAt(ia);
5206                        if (app.persistent) {
5207                            // we don't kill persistent processes
5208                            continue;
5209                        }
5210                        if (app.removed) {
5211                            procs.add(app);
5212                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5213                            app.removed = true;
5214                            procs.add(app);
5215                        }
5216                    }
5217                }
5218
5219                int N = procs.size();
5220                for (int i=0; i<N; i++) {
5221                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5222                }
5223                mAllowLowerMemLevel = true;
5224                updateOomAdjLocked();
5225                doLowMemReportIfNeededLocked(null);
5226            }
5227        } finally {
5228            Binder.restoreCallingIdentity(callingId);
5229        }
5230    }
5231
5232    @Override
5233    public void forceStopPackage(final String packageName, int userId) {
5234        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5235                != PackageManager.PERMISSION_GRANTED) {
5236            String msg = "Permission Denial: forceStopPackage() from pid="
5237                    + Binder.getCallingPid()
5238                    + ", uid=" + Binder.getCallingUid()
5239                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5240            Slog.w(TAG, msg);
5241            throw new SecurityException(msg);
5242        }
5243        final int callingPid = Binder.getCallingPid();
5244        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5245                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5246        long callingId = Binder.clearCallingIdentity();
5247        try {
5248            IPackageManager pm = AppGlobals.getPackageManager();
5249            synchronized(this) {
5250                int[] users = userId == UserHandle.USER_ALL
5251                        ? getUsersLocked() : new int[] { userId };
5252                for (int user : users) {
5253                    int pkgUid = -1;
5254                    try {
5255                        pkgUid = pm.getPackageUid(packageName, user);
5256                    } catch (RemoteException e) {
5257                    }
5258                    if (pkgUid == -1) {
5259                        Slog.w(TAG, "Invalid packageName: " + packageName);
5260                        continue;
5261                    }
5262                    try {
5263                        pm.setPackageStoppedState(packageName, true, user);
5264                    } catch (RemoteException e) {
5265                    } catch (IllegalArgumentException e) {
5266                        Slog.w(TAG, "Failed trying to unstop package "
5267                                + packageName + ": " + e);
5268                    }
5269                    if (isUserRunningLocked(user, false)) {
5270                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5271                    }
5272                }
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277    }
5278
5279    @Override
5280    public void addPackageDependency(String packageName) {
5281        synchronized (this) {
5282            int callingPid = Binder.getCallingPid();
5283            if (callingPid == Process.myPid()) {
5284                //  Yeah, um, no.
5285                Slog.w(TAG, "Can't addPackageDependency on system process");
5286                return;
5287            }
5288            ProcessRecord proc;
5289            synchronized (mPidsSelfLocked) {
5290                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5291            }
5292            if (proc != null) {
5293                if (proc.pkgDeps == null) {
5294                    proc.pkgDeps = new ArraySet<String>(1);
5295                }
5296                proc.pkgDeps.add(packageName);
5297            }
5298        }
5299    }
5300
5301    /*
5302     * The pkg name and app id have to be specified.
5303     */
5304    @Override
5305    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5306        if (pkg == null) {
5307            return;
5308        }
5309        // Make sure the uid is valid.
5310        if (appid < 0) {
5311            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5312            return;
5313        }
5314        int callerUid = Binder.getCallingUid();
5315        // Only the system server can kill an application
5316        if (callerUid == Process.SYSTEM_UID) {
5317            // Post an aysnc message to kill the application
5318            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5319            msg.arg1 = appid;
5320            msg.arg2 = 0;
5321            Bundle bundle = new Bundle();
5322            bundle.putString("pkg", pkg);
5323            bundle.putString("reason", reason);
5324            msg.obj = bundle;
5325            mHandler.sendMessage(msg);
5326        } else {
5327            throw new SecurityException(callerUid + " cannot kill pkg: " +
5328                    pkg);
5329        }
5330    }
5331
5332    @Override
5333    public void closeSystemDialogs(String reason) {
5334        enforceNotIsolatedCaller("closeSystemDialogs");
5335
5336        final int pid = Binder.getCallingPid();
5337        final int uid = Binder.getCallingUid();
5338        final long origId = Binder.clearCallingIdentity();
5339        try {
5340            synchronized (this) {
5341                // Only allow this from foreground processes, so that background
5342                // applications can't abuse it to prevent system UI from being shown.
5343                if (uid >= Process.FIRST_APPLICATION_UID) {
5344                    ProcessRecord proc;
5345                    synchronized (mPidsSelfLocked) {
5346                        proc = mPidsSelfLocked.get(pid);
5347                    }
5348                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5349                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5350                                + " from background process " + proc);
5351                        return;
5352                    }
5353                }
5354                closeSystemDialogsLocked(reason);
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(origId);
5358        }
5359    }
5360
5361    void closeSystemDialogsLocked(String reason) {
5362        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5363        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5364                | Intent.FLAG_RECEIVER_FOREGROUND);
5365        if (reason != null) {
5366            intent.putExtra("reason", reason);
5367        }
5368        mWindowManager.closeSystemDialogs(reason);
5369
5370        mStackSupervisor.closeSystemDialogsLocked();
5371
5372        broadcastIntentLocked(null, null, intent, null,
5373                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5374                Process.SYSTEM_UID, UserHandle.USER_ALL);
5375    }
5376
5377    @Override
5378    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5379        enforceNotIsolatedCaller("getProcessMemoryInfo");
5380        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5381        for (int i=pids.length-1; i>=0; i--) {
5382            ProcessRecord proc;
5383            int oomAdj;
5384            synchronized (this) {
5385                synchronized (mPidsSelfLocked) {
5386                    proc = mPidsSelfLocked.get(pids[i]);
5387                    oomAdj = proc != null ? proc.setAdj : 0;
5388                }
5389            }
5390            infos[i] = new Debug.MemoryInfo();
5391            Debug.getMemoryInfo(pids[i], infos[i]);
5392            if (proc != null) {
5393                synchronized (this) {
5394                    if (proc.thread != null && proc.setAdj == oomAdj) {
5395                        // Record this for posterity if the process has been stable.
5396                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5397                                infos[i].getTotalUss(), false, proc.pkgList);
5398                    }
5399                }
5400            }
5401        }
5402        return infos;
5403    }
5404
5405    @Override
5406    public long[] getProcessPss(int[] pids) {
5407        enforceNotIsolatedCaller("getProcessPss");
5408        long[] pss = new long[pids.length];
5409        for (int i=pids.length-1; i>=0; i--) {
5410            ProcessRecord proc;
5411            int oomAdj;
5412            synchronized (this) {
5413                synchronized (mPidsSelfLocked) {
5414                    proc = mPidsSelfLocked.get(pids[i]);
5415                    oomAdj = proc != null ? proc.setAdj : 0;
5416                }
5417            }
5418            long[] tmpUss = new long[1];
5419            pss[i] = Debug.getPss(pids[i], tmpUss);
5420            if (proc != null) {
5421                synchronized (this) {
5422                    if (proc.thread != null && proc.setAdj == oomAdj) {
5423                        // Record this for posterity if the process has been stable.
5424                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5425                    }
5426                }
5427            }
5428        }
5429        return pss;
5430    }
5431
5432    @Override
5433    public void killApplicationProcess(String processName, int uid) {
5434        if (processName == null) {
5435            return;
5436        }
5437
5438        int callerUid = Binder.getCallingUid();
5439        // Only the system server can kill an application
5440        if (callerUid == Process.SYSTEM_UID) {
5441            synchronized (this) {
5442                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5443                if (app != null && app.thread != null) {
5444                    try {
5445                        app.thread.scheduleSuicide();
5446                    } catch (RemoteException e) {
5447                        // If the other end already died, then our work here is done.
5448                    }
5449                } else {
5450                    Slog.w(TAG, "Process/uid not found attempting kill of "
5451                            + processName + " / " + uid);
5452                }
5453            }
5454        } else {
5455            throw new SecurityException(callerUid + " cannot kill app process: " +
5456                    processName);
5457        }
5458    }
5459
5460    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5461        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5462                false, true, false, false, UserHandle.getUserId(uid), reason);
5463        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5464                Uri.fromParts("package", packageName, null));
5465        if (!mProcessesReady) {
5466            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5467                    | Intent.FLAG_RECEIVER_FOREGROUND);
5468        }
5469        intent.putExtra(Intent.EXTRA_UID, uid);
5470        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5471        broadcastIntentLocked(null, null, intent,
5472                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5473                false, false,
5474                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5475    }
5476
5477    private void forceStopUserLocked(int userId, String reason) {
5478        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5479        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5480        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5481                | Intent.FLAG_RECEIVER_FOREGROUND);
5482        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5483        broadcastIntentLocked(null, null, intent,
5484                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5485                false, false,
5486                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5487    }
5488
5489    private final boolean killPackageProcessesLocked(String packageName, int appId,
5490            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5491            boolean doit, boolean evenPersistent, String reason) {
5492        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5493
5494        // Remove all processes this package may have touched: all with the
5495        // same UID (except for the system or root user), and all whose name
5496        // matches the package name.
5497        final int NP = mProcessNames.getMap().size();
5498        for (int ip=0; ip<NP; ip++) {
5499            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5500            final int NA = apps.size();
5501            for (int ia=0; ia<NA; ia++) {
5502                ProcessRecord app = apps.valueAt(ia);
5503                if (app.persistent && !evenPersistent) {
5504                    // we don't kill persistent processes
5505                    continue;
5506                }
5507                if (app.removed) {
5508                    if (doit) {
5509                        procs.add(app);
5510                    }
5511                    continue;
5512                }
5513
5514                // Skip process if it doesn't meet our oom adj requirement.
5515                if (app.setAdj < minOomAdj) {
5516                    continue;
5517                }
5518
5519                // If no package is specified, we call all processes under the
5520                // give user id.
5521                if (packageName == null) {
5522                    if (app.userId != userId) {
5523                        continue;
5524                    }
5525                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5526                        continue;
5527                    }
5528                // Package has been specified, we want to hit all processes
5529                // that match it.  We need to qualify this by the processes
5530                // that are running under the specified app and user ID.
5531                } else {
5532                    final boolean isDep = app.pkgDeps != null
5533                            && app.pkgDeps.contains(packageName);
5534                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5535                        continue;
5536                    }
5537                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5538                        continue;
5539                    }
5540                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5541                        continue;
5542                    }
5543                }
5544
5545                // Process has passed all conditions, kill it!
5546                if (!doit) {
5547                    return true;
5548                }
5549                app.removed = true;
5550                procs.add(app);
5551            }
5552        }
5553
5554        int N = procs.size();
5555        for (int i=0; i<N; i++) {
5556            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5557        }
5558        updateOomAdjLocked();
5559        return N > 0;
5560    }
5561
5562    private final boolean forceStopPackageLocked(String name, int appId,
5563            boolean callerWillRestart, boolean purgeCache, boolean doit,
5564            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5565        int i;
5566        int N;
5567
5568        if (userId == UserHandle.USER_ALL && name == null) {
5569            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5570        }
5571
5572        if (appId < 0 && name != null) {
5573            try {
5574                appId = UserHandle.getAppId(
5575                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5576            } catch (RemoteException e) {
5577            }
5578        }
5579
5580        if (doit) {
5581            if (name != null) {
5582                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5583                        + " user=" + userId + ": " + reason);
5584            } else {
5585                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5586            }
5587
5588            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5589            for (int ip=pmap.size()-1; ip>=0; ip--) {
5590                SparseArray<Long> ba = pmap.valueAt(ip);
5591                for (i=ba.size()-1; i>=0; i--) {
5592                    boolean remove = false;
5593                    final int entUid = ba.keyAt(i);
5594                    if (name != null) {
5595                        if (userId == UserHandle.USER_ALL) {
5596                            if (UserHandle.getAppId(entUid) == appId) {
5597                                remove = true;
5598                            }
5599                        } else {
5600                            if (entUid == UserHandle.getUid(userId, appId)) {
5601                                remove = true;
5602                            }
5603                        }
5604                    } else if (UserHandle.getUserId(entUid) == userId) {
5605                        remove = true;
5606                    }
5607                    if (remove) {
5608                        ba.removeAt(i);
5609                    }
5610                }
5611                if (ba.size() == 0) {
5612                    pmap.removeAt(ip);
5613                }
5614            }
5615        }
5616
5617        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5618                -100, callerWillRestart, true, doit, evenPersistent,
5619                name == null ? ("stop user " + userId) : ("stop " + name));
5620
5621        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5622            if (!doit) {
5623                return true;
5624            }
5625            didSomething = true;
5626        }
5627
5628        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5629            if (!doit) {
5630                return true;
5631            }
5632            didSomething = true;
5633        }
5634
5635        if (name == null) {
5636            // Remove all sticky broadcasts from this user.
5637            mStickyBroadcasts.remove(userId);
5638        }
5639
5640        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5641        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5642                userId, providers)) {
5643            if (!doit) {
5644                return true;
5645            }
5646            didSomething = true;
5647        }
5648        N = providers.size();
5649        for (i=0; i<N; i++) {
5650            removeDyingProviderLocked(null, providers.get(i), true);
5651        }
5652
5653        // Remove transient permissions granted from/to this package/user
5654        removeUriPermissionsForPackageLocked(name, userId, false);
5655
5656        if (name == null || uninstalling) {
5657            // Remove pending intents.  For now we only do this when force
5658            // stopping users, because we have some problems when doing this
5659            // for packages -- app widgets are not currently cleaned up for
5660            // such packages, so they can be left with bad pending intents.
5661            if (mIntentSenderRecords.size() > 0) {
5662                Iterator<WeakReference<PendingIntentRecord>> it
5663                        = mIntentSenderRecords.values().iterator();
5664                while (it.hasNext()) {
5665                    WeakReference<PendingIntentRecord> wpir = it.next();
5666                    if (wpir == null) {
5667                        it.remove();
5668                        continue;
5669                    }
5670                    PendingIntentRecord pir = wpir.get();
5671                    if (pir == null) {
5672                        it.remove();
5673                        continue;
5674                    }
5675                    if (name == null) {
5676                        // Stopping user, remove all objects for the user.
5677                        if (pir.key.userId != userId) {
5678                            // Not the same user, skip it.
5679                            continue;
5680                        }
5681                    } else {
5682                        if (UserHandle.getAppId(pir.uid) != appId) {
5683                            // Different app id, skip it.
5684                            continue;
5685                        }
5686                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5687                            // Different user, skip it.
5688                            continue;
5689                        }
5690                        if (!pir.key.packageName.equals(name)) {
5691                            // Different package, skip it.
5692                            continue;
5693                        }
5694                    }
5695                    if (!doit) {
5696                        return true;
5697                    }
5698                    didSomething = true;
5699                    it.remove();
5700                    pir.canceled = true;
5701                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5702                        pir.key.activity.pendingResults.remove(pir.ref);
5703                    }
5704                }
5705            }
5706        }
5707
5708        if (doit) {
5709            if (purgeCache && name != null) {
5710                AttributeCache ac = AttributeCache.instance();
5711                if (ac != null) {
5712                    ac.removePackage(name);
5713                }
5714            }
5715            if (mBooted) {
5716                mStackSupervisor.resumeTopActivitiesLocked();
5717                mStackSupervisor.scheduleIdleLocked();
5718            }
5719        }
5720
5721        return didSomething;
5722    }
5723
5724    private final boolean removeProcessLocked(ProcessRecord app,
5725            boolean callerWillRestart, boolean allowRestart, String reason) {
5726        final String name = app.processName;
5727        final int uid = app.uid;
5728        if (DEBUG_PROCESSES) Slog.d(
5729            TAG, "Force removing proc " + app.toShortString() + " (" + name
5730            + "/" + uid + ")");
5731
5732        mProcessNames.remove(name, uid);
5733        mIsolatedProcesses.remove(app.uid);
5734        if (mHeavyWeightProcess == app) {
5735            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5736                    mHeavyWeightProcess.userId, 0));
5737            mHeavyWeightProcess = null;
5738        }
5739        boolean needRestart = false;
5740        if (app.pid > 0 && app.pid != MY_PID) {
5741            int pid = app.pid;
5742            synchronized (mPidsSelfLocked) {
5743                mPidsSelfLocked.remove(pid);
5744                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5745            }
5746            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5747            if (app.isolated) {
5748                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5749            }
5750            app.kill(reason, true);
5751            handleAppDiedLocked(app, true, allowRestart);
5752            removeLruProcessLocked(app);
5753
5754            if (app.persistent && !app.isolated) {
5755                if (!callerWillRestart) {
5756                    addAppLocked(app.info, false, null /* ABI override */);
5757                } else {
5758                    needRestart = true;
5759                }
5760            }
5761        } else {
5762            mRemovedProcesses.add(app);
5763        }
5764
5765        return needRestart;
5766    }
5767
5768    private final void processStartTimedOutLocked(ProcessRecord app) {
5769        final int pid = app.pid;
5770        boolean gone = false;
5771        synchronized (mPidsSelfLocked) {
5772            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5773            if (knownApp != null && knownApp.thread == null) {
5774                mPidsSelfLocked.remove(pid);
5775                gone = true;
5776            }
5777        }
5778
5779        if (gone) {
5780            Slog.w(TAG, "Process " + app + " failed to attach");
5781            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5782                    pid, app.uid, app.processName);
5783            mProcessNames.remove(app.processName, app.uid);
5784            mIsolatedProcesses.remove(app.uid);
5785            if (mHeavyWeightProcess == app) {
5786                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5787                        mHeavyWeightProcess.userId, 0));
5788                mHeavyWeightProcess = null;
5789            }
5790            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5791            if (app.isolated) {
5792                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5793            }
5794            // Take care of any launching providers waiting for this process.
5795            checkAppInLaunchingProvidersLocked(app, true);
5796            // Take care of any services that are waiting for the process.
5797            mServices.processStartTimedOutLocked(app);
5798            app.kill("start timeout", true);
5799            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5800                Slog.w(TAG, "Unattached app died before backup, skipping");
5801                try {
5802                    IBackupManager bm = IBackupManager.Stub.asInterface(
5803                            ServiceManager.getService(Context.BACKUP_SERVICE));
5804                    bm.agentDisconnected(app.info.packageName);
5805                } catch (RemoteException e) {
5806                    // Can't happen; the backup manager is local
5807                }
5808            }
5809            if (isPendingBroadcastProcessLocked(pid)) {
5810                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5811                skipPendingBroadcastLocked(pid);
5812            }
5813        } else {
5814            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5815        }
5816    }
5817
5818    private final boolean attachApplicationLocked(IApplicationThread thread,
5819            int pid) {
5820
5821        // Find the application record that is being attached...  either via
5822        // the pid if we are running in multiple processes, or just pull the
5823        // next app record if we are emulating process with anonymous threads.
5824        ProcessRecord app;
5825        if (pid != MY_PID && pid >= 0) {
5826            synchronized (mPidsSelfLocked) {
5827                app = mPidsSelfLocked.get(pid);
5828            }
5829        } else {
5830            app = null;
5831        }
5832
5833        if (app == null) {
5834            Slog.w(TAG, "No pending application record for pid " + pid
5835                    + " (IApplicationThread " + thread + "); dropping process");
5836            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5837            if (pid > 0 && pid != MY_PID) {
5838                Process.killProcessQuiet(pid);
5839                //TODO: Process.killProcessGroup(app.info.uid, pid);
5840            } else {
5841                try {
5842                    thread.scheduleExit();
5843                } catch (Exception e) {
5844                    // Ignore exceptions.
5845                }
5846            }
5847            return false;
5848        }
5849
5850        // If this application record is still attached to a previous
5851        // process, clean it up now.
5852        if (app.thread != null) {
5853            handleAppDiedLocked(app, true, true);
5854        }
5855
5856        // Tell the process all about itself.
5857
5858        if (localLOGV) Slog.v(
5859                TAG, "Binding process pid " + pid + " to record " + app);
5860
5861        final String processName = app.processName;
5862        try {
5863            AppDeathRecipient adr = new AppDeathRecipient(
5864                    app, pid, thread);
5865            thread.asBinder().linkToDeath(adr, 0);
5866            app.deathRecipient = adr;
5867        } catch (RemoteException e) {
5868            app.resetPackageList(mProcessStats);
5869            startProcessLocked(app, "link fail", processName);
5870            return false;
5871        }
5872
5873        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5874
5875        app.makeActive(thread, mProcessStats);
5876        app.curAdj = app.setAdj = -100;
5877        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5878        app.forcingToForeground = null;
5879        updateProcessForegroundLocked(app, false, false);
5880        app.hasShownUi = false;
5881        app.debugging = false;
5882        app.cached = false;
5883
5884        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5885
5886        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5887        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5888
5889        if (!normalMode) {
5890            Slog.i(TAG, "Launching preboot mode app: " + app);
5891        }
5892
5893        if (localLOGV) Slog.v(
5894            TAG, "New app record " + app
5895            + " thread=" + thread.asBinder() + " pid=" + pid);
5896        try {
5897            int testMode = IApplicationThread.DEBUG_OFF;
5898            if (mDebugApp != null && mDebugApp.equals(processName)) {
5899                testMode = mWaitForDebugger
5900                    ? IApplicationThread.DEBUG_WAIT
5901                    : IApplicationThread.DEBUG_ON;
5902                app.debugging = true;
5903                if (mDebugTransient) {
5904                    mDebugApp = mOrigDebugApp;
5905                    mWaitForDebugger = mOrigWaitForDebugger;
5906                }
5907            }
5908            String profileFile = app.instrumentationProfileFile;
5909            ParcelFileDescriptor profileFd = null;
5910            int samplingInterval = 0;
5911            boolean profileAutoStop = false;
5912            if (mProfileApp != null && mProfileApp.equals(processName)) {
5913                mProfileProc = app;
5914                profileFile = mProfileFile;
5915                profileFd = mProfileFd;
5916                samplingInterval = mSamplingInterval;
5917                profileAutoStop = mAutoStopProfiler;
5918            }
5919            boolean enableOpenGlTrace = false;
5920            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5921                enableOpenGlTrace = true;
5922                mOpenGlTraceApp = null;
5923            }
5924
5925            // If the app is being launched for restore or full backup, set it up specially
5926            boolean isRestrictedBackupMode = false;
5927            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5928                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5929                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5930                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5931            }
5932
5933            ensurePackageDexOpt(app.instrumentationInfo != null
5934                    ? app.instrumentationInfo.packageName
5935                    : app.info.packageName);
5936            if (app.instrumentationClass != null) {
5937                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5938            }
5939            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5940                    + processName + " with config " + mConfiguration);
5941            ApplicationInfo appInfo = app.instrumentationInfo != null
5942                    ? app.instrumentationInfo : app.info;
5943            app.compat = compatibilityInfoForPackageLocked(appInfo);
5944            if (profileFd != null) {
5945                profileFd = profileFd.dup();
5946            }
5947            ProfilerInfo profilerInfo = profileFile == null ? null
5948                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5949            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5950                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5951                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5952                    isRestrictedBackupMode || !normalMode, app.persistent,
5953                    new Configuration(mConfiguration), app.compat,
5954                    getCommonServicesLocked(app.isolated),
5955                    mCoreSettingsObserver.getCoreSettingsLocked());
5956            updateLruProcessLocked(app, false, null);
5957            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5958        } catch (Exception e) {
5959            // todo: Yikes!  What should we do?  For now we will try to
5960            // start another process, but that could easily get us in
5961            // an infinite loop of restarting processes...
5962            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5963
5964            app.resetPackageList(mProcessStats);
5965            app.unlinkDeathRecipient();
5966            startProcessLocked(app, "bind fail", processName);
5967            return false;
5968        }
5969
5970        // Remove this record from the list of starting applications.
5971        mPersistentStartingProcesses.remove(app);
5972        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5973                "Attach application locked removing on hold: " + app);
5974        mProcessesOnHold.remove(app);
5975
5976        boolean badApp = false;
5977        boolean didSomething = false;
5978
5979        // See if the top visible activity is waiting to run in this process...
5980        if (normalMode) {
5981            try {
5982                if (mStackSupervisor.attachApplicationLocked(app)) {
5983                    didSomething = true;
5984                }
5985            } catch (Exception e) {
5986                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5987                badApp = true;
5988            }
5989        }
5990
5991        // Find any services that should be running in this process...
5992        if (!badApp) {
5993            try {
5994                didSomething |= mServices.attachApplicationLocked(app, processName);
5995            } catch (Exception e) {
5996                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5997                badApp = true;
5998            }
5999        }
6000
6001        // Check if a next-broadcast receiver is in this process...
6002        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6003            try {
6004                didSomething |= sendPendingBroadcastsLocked(app);
6005            } catch (Exception e) {
6006                // If the app died trying to launch the receiver we declare it 'bad'
6007                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6008                badApp = true;
6009            }
6010        }
6011
6012        // Check whether the next backup agent is in this process...
6013        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6014            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6015            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6016            try {
6017                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6018                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6019                        mBackupTarget.backupMode);
6020            } catch (Exception e) {
6021                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6022                badApp = true;
6023            }
6024        }
6025
6026        if (badApp) {
6027            app.kill("error during init", true);
6028            handleAppDiedLocked(app, false, true);
6029            return false;
6030        }
6031
6032        if (!didSomething) {
6033            updateOomAdjLocked();
6034        }
6035
6036        return true;
6037    }
6038
6039    @Override
6040    public final void attachApplication(IApplicationThread thread) {
6041        synchronized (this) {
6042            int callingPid = Binder.getCallingPid();
6043            final long origId = Binder.clearCallingIdentity();
6044            attachApplicationLocked(thread, callingPid);
6045            Binder.restoreCallingIdentity(origId);
6046        }
6047    }
6048
6049    @Override
6050    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6051        final long origId = Binder.clearCallingIdentity();
6052        synchronized (this) {
6053            ActivityStack stack = ActivityRecord.getStackLocked(token);
6054            if (stack != null) {
6055                ActivityRecord r =
6056                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6057                if (stopProfiling) {
6058                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6059                        try {
6060                            mProfileFd.close();
6061                        } catch (IOException e) {
6062                        }
6063                        clearProfilerLocked();
6064                    }
6065                }
6066            }
6067        }
6068        Binder.restoreCallingIdentity(origId);
6069    }
6070
6071    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6072        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6073                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6074    }
6075
6076    void enableScreenAfterBoot() {
6077        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6078                SystemClock.uptimeMillis());
6079        mWindowManager.enableScreenAfterBoot();
6080
6081        synchronized (this) {
6082            updateEventDispatchingLocked();
6083        }
6084    }
6085
6086    @Override
6087    public void showBootMessage(final CharSequence msg, final boolean always) {
6088        enforceNotIsolatedCaller("showBootMessage");
6089        mWindowManager.showBootMessage(msg, always);
6090    }
6091
6092    @Override
6093    public void keyguardWaitingForActivityDrawn() {
6094        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6095        final long token = Binder.clearCallingIdentity();
6096        try {
6097            synchronized (this) {
6098                if (DEBUG_LOCKSCREEN) logLockScreen("");
6099                mWindowManager.keyguardWaitingForActivityDrawn();
6100                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6101                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6102                    updateSleepIfNeededLocked();
6103                }
6104            }
6105        } finally {
6106            Binder.restoreCallingIdentity(token);
6107        }
6108    }
6109
6110    final void finishBooting() {
6111        synchronized (this) {
6112            if (!mBootAnimationComplete) {
6113                mCallFinishBooting = true;
6114                return;
6115            }
6116            mCallFinishBooting = false;
6117        }
6118
6119        ArraySet<String> completedIsas = new ArraySet<String>();
6120        for (String abi : Build.SUPPORTED_ABIS) {
6121            Process.establishZygoteConnectionForAbi(abi);
6122            final String instructionSet = VMRuntime.getInstructionSet(abi);
6123            if (!completedIsas.contains(instructionSet)) {
6124                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6125                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6126                }
6127                completedIsas.add(instructionSet);
6128            }
6129        }
6130
6131        IntentFilter pkgFilter = new IntentFilter();
6132        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6133        pkgFilter.addDataScheme("package");
6134        mContext.registerReceiver(new BroadcastReceiver() {
6135            @Override
6136            public void onReceive(Context context, Intent intent) {
6137                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6138                if (pkgs != null) {
6139                    for (String pkg : pkgs) {
6140                        synchronized (ActivityManagerService.this) {
6141                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6142                                    0, "finished booting")) {
6143                                setResultCode(Activity.RESULT_OK);
6144                                return;
6145                            }
6146                        }
6147                    }
6148                }
6149            }
6150        }, pkgFilter);
6151
6152        // Let system services know.
6153        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6154
6155        synchronized (this) {
6156            // Ensure that any processes we had put on hold are now started
6157            // up.
6158            final int NP = mProcessesOnHold.size();
6159            if (NP > 0) {
6160                ArrayList<ProcessRecord> procs =
6161                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6162                for (int ip=0; ip<NP; ip++) {
6163                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6164                            + procs.get(ip));
6165                    startProcessLocked(procs.get(ip), "on-hold", null);
6166                }
6167            }
6168
6169            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6170                // Start looking for apps that are abusing wake locks.
6171                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6172                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6173                // Tell anyone interested that we are done booting!
6174                SystemProperties.set("sys.boot_completed", "1");
6175
6176                // And trigger dev.bootcomplete if we are not showing encryption progress
6177                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6178                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6179                    SystemProperties.set("dev.bootcomplete", "1");
6180                }
6181                for (int i=0; i<mStartedUsers.size(); i++) {
6182                    UserStartedState uss = mStartedUsers.valueAt(i);
6183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6184                        uss.mState = UserStartedState.STATE_RUNNING;
6185                        final int userId = mStartedUsers.keyAt(i);
6186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6189                        broadcastIntentLocked(null, null, intent, null,
6190                                new IIntentReceiver.Stub() {
6191                                    @Override
6192                                    public void performReceive(Intent intent, int resultCode,
6193                                            String data, Bundle extras, boolean ordered,
6194                                            boolean sticky, int sendingUser) {
6195                                        synchronized (ActivityManagerService.this) {
6196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6197                                                    true, false);
6198                                        }
6199                                    }
6200                                },
6201                                0, null, null,
6202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6204                                userId);
6205                    }
6206                }
6207                scheduleStartProfilesLocked();
6208            }
6209        }
6210    }
6211
6212    @Override
6213    public void bootAnimationComplete() {
6214        final boolean callFinishBooting;
6215        synchronized (this) {
6216            callFinishBooting = mCallFinishBooting;
6217            mBootAnimationComplete = true;
6218        }
6219        if (callFinishBooting) {
6220            finishBooting();
6221        }
6222    }
6223
6224    final void ensureBootCompleted() {
6225        boolean booting;
6226        boolean enableScreen;
6227        synchronized (this) {
6228            booting = mBooting;
6229            mBooting = false;
6230            enableScreen = !mBooted;
6231            mBooted = true;
6232        }
6233
6234        if (booting) {
6235            finishBooting();
6236        }
6237
6238        if (enableScreen) {
6239            enableScreenAfterBoot();
6240        }
6241    }
6242
6243    @Override
6244    public final void activityResumed(IBinder token) {
6245        final long origId = Binder.clearCallingIdentity();
6246        synchronized(this) {
6247            ActivityStack stack = ActivityRecord.getStackLocked(token);
6248            if (stack != null) {
6249                ActivityRecord.activityResumedLocked(token);
6250            }
6251        }
6252        Binder.restoreCallingIdentity(origId);
6253    }
6254
6255    @Override
6256    public final void activityPaused(IBinder token) {
6257        final long origId = Binder.clearCallingIdentity();
6258        synchronized(this) {
6259            ActivityStack stack = ActivityRecord.getStackLocked(token);
6260            if (stack != null) {
6261                stack.activityPausedLocked(token, false);
6262            }
6263        }
6264        Binder.restoreCallingIdentity(origId);
6265    }
6266
6267    @Override
6268    public final void activityStopped(IBinder token, Bundle icicle,
6269            PersistableBundle persistentState, CharSequence description) {
6270        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6271
6272        // Refuse possible leaked file descriptors
6273        if (icicle != null && icicle.hasFileDescriptors()) {
6274            throw new IllegalArgumentException("File descriptors passed in Bundle");
6275        }
6276
6277        final long origId = Binder.clearCallingIdentity();
6278
6279        synchronized (this) {
6280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6281            if (r != null) {
6282                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6283            }
6284        }
6285
6286        trimApplications();
6287
6288        Binder.restoreCallingIdentity(origId);
6289    }
6290
6291    @Override
6292    public final void activityDestroyed(IBinder token) {
6293        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6294        synchronized (this) {
6295            ActivityStack stack = ActivityRecord.getStackLocked(token);
6296            if (stack != null) {
6297                stack.activityDestroyedLocked(token);
6298            }
6299        }
6300    }
6301
6302    @Override
6303    public final void backgroundResourcesReleased(IBinder token) {
6304        final long origId = Binder.clearCallingIdentity();
6305        try {
6306            synchronized (this) {
6307                ActivityStack stack = ActivityRecord.getStackLocked(token);
6308                if (stack != null) {
6309                    stack.backgroundResourcesReleased();
6310                }
6311            }
6312        } finally {
6313            Binder.restoreCallingIdentity(origId);
6314        }
6315    }
6316
6317    @Override
6318    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6319        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6320    }
6321
6322    @Override
6323    public final void notifyEnterAnimationComplete(IBinder token) {
6324        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6325    }
6326
6327    @Override
6328    public String getCallingPackage(IBinder token) {
6329        synchronized (this) {
6330            ActivityRecord r = getCallingRecordLocked(token);
6331            return r != null ? r.info.packageName : null;
6332        }
6333    }
6334
6335    @Override
6336    public ComponentName getCallingActivity(IBinder token) {
6337        synchronized (this) {
6338            ActivityRecord r = getCallingRecordLocked(token);
6339            return r != null ? r.intent.getComponent() : null;
6340        }
6341    }
6342
6343    private ActivityRecord getCallingRecordLocked(IBinder token) {
6344        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6345        if (r == null) {
6346            return null;
6347        }
6348        return r.resultTo;
6349    }
6350
6351    @Override
6352    public ComponentName getActivityClassForToken(IBinder token) {
6353        synchronized(this) {
6354            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6355            if (r == null) {
6356                return null;
6357            }
6358            return r.intent.getComponent();
6359        }
6360    }
6361
6362    @Override
6363    public String getPackageForToken(IBinder token) {
6364        synchronized(this) {
6365            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6366            if (r == null) {
6367                return null;
6368            }
6369            return r.packageName;
6370        }
6371    }
6372
6373    @Override
6374    public IIntentSender getIntentSender(int type,
6375            String packageName, IBinder token, String resultWho,
6376            int requestCode, Intent[] intents, String[] resolvedTypes,
6377            int flags, Bundle options, int userId) {
6378        enforceNotIsolatedCaller("getIntentSender");
6379        // Refuse possible leaked file descriptors
6380        if (intents != null) {
6381            if (intents.length < 1) {
6382                throw new IllegalArgumentException("Intents array length must be >= 1");
6383            }
6384            for (int i=0; i<intents.length; i++) {
6385                Intent intent = intents[i];
6386                if (intent != null) {
6387                    if (intent.hasFileDescriptors()) {
6388                        throw new IllegalArgumentException("File descriptors passed in Intent");
6389                    }
6390                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6391                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6392                        throw new IllegalArgumentException(
6393                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6394                    }
6395                    intents[i] = new Intent(intent);
6396                }
6397            }
6398            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6399                throw new IllegalArgumentException(
6400                        "Intent array length does not match resolvedTypes length");
6401            }
6402        }
6403        if (options != null) {
6404            if (options.hasFileDescriptors()) {
6405                throw new IllegalArgumentException("File descriptors passed in options");
6406            }
6407        }
6408
6409        synchronized(this) {
6410            int callingUid = Binder.getCallingUid();
6411            int origUserId = userId;
6412            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6413                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6414                    ALLOW_NON_FULL, "getIntentSender", null);
6415            if (origUserId == UserHandle.USER_CURRENT) {
6416                // We don't want to evaluate this until the pending intent is
6417                // actually executed.  However, we do want to always do the
6418                // security checking for it above.
6419                userId = UserHandle.USER_CURRENT;
6420            }
6421            try {
6422                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6423                    int uid = AppGlobals.getPackageManager()
6424                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6425                    if (!UserHandle.isSameApp(callingUid, uid)) {
6426                        String msg = "Permission Denial: getIntentSender() from pid="
6427                            + Binder.getCallingPid()
6428                            + ", uid=" + Binder.getCallingUid()
6429                            + ", (need uid=" + uid + ")"
6430                            + " is not allowed to send as package " + packageName;
6431                        Slog.w(TAG, msg);
6432                        throw new SecurityException(msg);
6433                    }
6434                }
6435
6436                return getIntentSenderLocked(type, packageName, callingUid, userId,
6437                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6438
6439            } catch (RemoteException e) {
6440                throw new SecurityException(e);
6441            }
6442        }
6443    }
6444
6445    IIntentSender getIntentSenderLocked(int type, String packageName,
6446            int callingUid, int userId, IBinder token, String resultWho,
6447            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6448            Bundle options) {
6449        if (DEBUG_MU)
6450            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6451        ActivityRecord activity = null;
6452        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6453            activity = ActivityRecord.isInStackLocked(token);
6454            if (activity == null) {
6455                return null;
6456            }
6457            if (activity.finishing) {
6458                return null;
6459            }
6460        }
6461
6462        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6463        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6464        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6465        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6466                |PendingIntent.FLAG_UPDATE_CURRENT);
6467
6468        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6469                type, packageName, activity, resultWho,
6470                requestCode, intents, resolvedTypes, flags, options, userId);
6471        WeakReference<PendingIntentRecord> ref;
6472        ref = mIntentSenderRecords.get(key);
6473        PendingIntentRecord rec = ref != null ? ref.get() : null;
6474        if (rec != null) {
6475            if (!cancelCurrent) {
6476                if (updateCurrent) {
6477                    if (rec.key.requestIntent != null) {
6478                        rec.key.requestIntent.replaceExtras(intents != null ?
6479                                intents[intents.length - 1] : null);
6480                    }
6481                    if (intents != null) {
6482                        intents[intents.length-1] = rec.key.requestIntent;
6483                        rec.key.allIntents = intents;
6484                        rec.key.allResolvedTypes = resolvedTypes;
6485                    } else {
6486                        rec.key.allIntents = null;
6487                        rec.key.allResolvedTypes = null;
6488                    }
6489                }
6490                return rec;
6491            }
6492            rec.canceled = true;
6493            mIntentSenderRecords.remove(key);
6494        }
6495        if (noCreate) {
6496            return rec;
6497        }
6498        rec = new PendingIntentRecord(this, key, callingUid);
6499        mIntentSenderRecords.put(key, rec.ref);
6500        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6501            if (activity.pendingResults == null) {
6502                activity.pendingResults
6503                        = new HashSet<WeakReference<PendingIntentRecord>>();
6504            }
6505            activity.pendingResults.add(rec.ref);
6506        }
6507        return rec;
6508    }
6509
6510    @Override
6511    public void cancelIntentSender(IIntentSender sender) {
6512        if (!(sender instanceof PendingIntentRecord)) {
6513            return;
6514        }
6515        synchronized(this) {
6516            PendingIntentRecord rec = (PendingIntentRecord)sender;
6517            try {
6518                int uid = AppGlobals.getPackageManager()
6519                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6520                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6521                    String msg = "Permission Denial: cancelIntentSender() from pid="
6522                        + Binder.getCallingPid()
6523                        + ", uid=" + Binder.getCallingUid()
6524                        + " is not allowed to cancel packges "
6525                        + rec.key.packageName;
6526                    Slog.w(TAG, msg);
6527                    throw new SecurityException(msg);
6528                }
6529            } catch (RemoteException e) {
6530                throw new SecurityException(e);
6531            }
6532            cancelIntentSenderLocked(rec, true);
6533        }
6534    }
6535
6536    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6537        rec.canceled = true;
6538        mIntentSenderRecords.remove(rec.key);
6539        if (cleanActivity && rec.key.activity != null) {
6540            rec.key.activity.pendingResults.remove(rec.ref);
6541        }
6542    }
6543
6544    @Override
6545    public String getPackageForIntentSender(IIntentSender pendingResult) {
6546        if (!(pendingResult instanceof PendingIntentRecord)) {
6547            return null;
6548        }
6549        try {
6550            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6551            return res.key.packageName;
6552        } catch (ClassCastException e) {
6553        }
6554        return null;
6555    }
6556
6557    @Override
6558    public int getUidForIntentSender(IIntentSender sender) {
6559        if (sender instanceof PendingIntentRecord) {
6560            try {
6561                PendingIntentRecord res = (PendingIntentRecord)sender;
6562                return res.uid;
6563            } catch (ClassCastException e) {
6564            }
6565        }
6566        return -1;
6567    }
6568
6569    @Override
6570    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6571        if (!(pendingResult instanceof PendingIntentRecord)) {
6572            return false;
6573        }
6574        try {
6575            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6576            if (res.key.allIntents == null) {
6577                return false;
6578            }
6579            for (int i=0; i<res.key.allIntents.length; i++) {
6580                Intent intent = res.key.allIntents[i];
6581                if (intent.getPackage() != null && intent.getComponent() != null) {
6582                    return false;
6583                }
6584            }
6585            return true;
6586        } catch (ClassCastException e) {
6587        }
6588        return false;
6589    }
6590
6591    @Override
6592    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6593        if (!(pendingResult instanceof PendingIntentRecord)) {
6594            return false;
6595        }
6596        try {
6597            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6598            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6599                return true;
6600            }
6601            return false;
6602        } catch (ClassCastException e) {
6603        }
6604        return false;
6605    }
6606
6607    @Override
6608    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6609        if (!(pendingResult instanceof PendingIntentRecord)) {
6610            return null;
6611        }
6612        try {
6613            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6614            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6615        } catch (ClassCastException e) {
6616        }
6617        return null;
6618    }
6619
6620    @Override
6621    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6622        if (!(pendingResult instanceof PendingIntentRecord)) {
6623            return null;
6624        }
6625        try {
6626            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6627            Intent intent = res.key.requestIntent;
6628            if (intent != null) {
6629                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6630                        || res.lastTagPrefix.equals(prefix))) {
6631                    return res.lastTag;
6632                }
6633                res.lastTagPrefix = prefix;
6634                StringBuilder sb = new StringBuilder(128);
6635                if (prefix != null) {
6636                    sb.append(prefix);
6637                }
6638                if (intent.getAction() != null) {
6639                    sb.append(intent.getAction());
6640                } else if (intent.getComponent() != null) {
6641                    intent.getComponent().appendShortString(sb);
6642                } else {
6643                    sb.append("?");
6644                }
6645                return res.lastTag = sb.toString();
6646            }
6647        } catch (ClassCastException e) {
6648        }
6649        return null;
6650    }
6651
6652    @Override
6653    public void setProcessLimit(int max) {
6654        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6655                "setProcessLimit()");
6656        synchronized (this) {
6657            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6658            mProcessLimitOverride = max;
6659        }
6660        trimApplications();
6661    }
6662
6663    @Override
6664    public int getProcessLimit() {
6665        synchronized (this) {
6666            return mProcessLimitOverride;
6667        }
6668    }
6669
6670    void foregroundTokenDied(ForegroundToken token) {
6671        synchronized (ActivityManagerService.this) {
6672            synchronized (mPidsSelfLocked) {
6673                ForegroundToken cur
6674                    = mForegroundProcesses.get(token.pid);
6675                if (cur != token) {
6676                    return;
6677                }
6678                mForegroundProcesses.remove(token.pid);
6679                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6680                if (pr == null) {
6681                    return;
6682                }
6683                pr.forcingToForeground = null;
6684                updateProcessForegroundLocked(pr, false, false);
6685            }
6686            updateOomAdjLocked();
6687        }
6688    }
6689
6690    @Override
6691    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6692        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6693                "setProcessForeground()");
6694        synchronized(this) {
6695            boolean changed = false;
6696
6697            synchronized (mPidsSelfLocked) {
6698                ProcessRecord pr = mPidsSelfLocked.get(pid);
6699                if (pr == null && isForeground) {
6700                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6701                    return;
6702                }
6703                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6704                if (oldToken != null) {
6705                    oldToken.token.unlinkToDeath(oldToken, 0);
6706                    mForegroundProcesses.remove(pid);
6707                    if (pr != null) {
6708                        pr.forcingToForeground = null;
6709                    }
6710                    changed = true;
6711                }
6712                if (isForeground && token != null) {
6713                    ForegroundToken newToken = new ForegroundToken() {
6714                        @Override
6715                        public void binderDied() {
6716                            foregroundTokenDied(this);
6717                        }
6718                    };
6719                    newToken.pid = pid;
6720                    newToken.token = token;
6721                    try {
6722                        token.linkToDeath(newToken, 0);
6723                        mForegroundProcesses.put(pid, newToken);
6724                        pr.forcingToForeground = token;
6725                        changed = true;
6726                    } catch (RemoteException e) {
6727                        // If the process died while doing this, we will later
6728                        // do the cleanup with the process death link.
6729                    }
6730                }
6731            }
6732
6733            if (changed) {
6734                updateOomAdjLocked();
6735            }
6736        }
6737    }
6738
6739    // =========================================================
6740    // PERMISSIONS
6741    // =========================================================
6742
6743    static class PermissionController extends IPermissionController.Stub {
6744        ActivityManagerService mActivityManagerService;
6745        PermissionController(ActivityManagerService activityManagerService) {
6746            mActivityManagerService = activityManagerService;
6747        }
6748
6749        @Override
6750        public boolean checkPermission(String permission, int pid, int uid) {
6751            return mActivityManagerService.checkPermission(permission, pid,
6752                    uid) == PackageManager.PERMISSION_GRANTED;
6753        }
6754    }
6755
6756    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6757        @Override
6758        public int checkComponentPermission(String permission, int pid, int uid,
6759                int owningUid, boolean exported) {
6760            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6761                    owningUid, exported);
6762        }
6763
6764        @Override
6765        public Object getAMSLock() {
6766            return ActivityManagerService.this;
6767        }
6768    }
6769
6770    /**
6771     * This can be called with or without the global lock held.
6772     */
6773    int checkComponentPermission(String permission, int pid, int uid,
6774            int owningUid, boolean exported) {
6775        if (pid == MY_PID) {
6776            return PackageManager.PERMISSION_GRANTED;
6777        }
6778        return ActivityManager.checkComponentPermission(permission, uid,
6779                owningUid, exported);
6780    }
6781
6782    /**
6783     * As the only public entry point for permissions checking, this method
6784     * can enforce the semantic that requesting a check on a null global
6785     * permission is automatically denied.  (Internally a null permission
6786     * string is used when calling {@link #checkComponentPermission} in cases
6787     * when only uid-based security is needed.)
6788     *
6789     * This can be called with or without the global lock held.
6790     */
6791    @Override
6792    public int checkPermission(String permission, int pid, int uid) {
6793        if (permission == null) {
6794            return PackageManager.PERMISSION_DENIED;
6795        }
6796        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6797    }
6798
6799    @Override
6800    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6801        if (permission == null) {
6802            return PackageManager.PERMISSION_DENIED;
6803        }
6804
6805        // We might be performing an operation on behalf of an indirect binder
6806        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6807        // client identity accordingly before proceeding.
6808        Identity tlsIdentity = sCallerIdentity.get();
6809        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6810            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6811                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6812            uid = tlsIdentity.uid;
6813            pid = tlsIdentity.pid;
6814        }
6815
6816        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6817    }
6818
6819    /**
6820     * Binder IPC calls go through the public entry point.
6821     * This can be called with or without the global lock held.
6822     */
6823    int checkCallingPermission(String permission) {
6824        return checkPermission(permission,
6825                Binder.getCallingPid(),
6826                UserHandle.getAppId(Binder.getCallingUid()));
6827    }
6828
6829    /**
6830     * This can be called with or without the global lock held.
6831     */
6832    void enforceCallingPermission(String permission, String func) {
6833        if (checkCallingPermission(permission)
6834                == PackageManager.PERMISSION_GRANTED) {
6835            return;
6836        }
6837
6838        String msg = "Permission Denial: " + func + " from pid="
6839                + Binder.getCallingPid()
6840                + ", uid=" + Binder.getCallingUid()
6841                + " requires " + permission;
6842        Slog.w(TAG, msg);
6843        throw new SecurityException(msg);
6844    }
6845
6846    /**
6847     * Determine if UID is holding permissions required to access {@link Uri} in
6848     * the given {@link ProviderInfo}. Final permission checking is always done
6849     * in {@link ContentProvider}.
6850     */
6851    private final boolean checkHoldingPermissionsLocked(
6852            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6853        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6854                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6855        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6856            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6857                    != PERMISSION_GRANTED) {
6858                return false;
6859            }
6860        }
6861        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6862    }
6863
6864    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6865            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6866        if (pi.applicationInfo.uid == uid) {
6867            return true;
6868        } else if (!pi.exported) {
6869            return false;
6870        }
6871
6872        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6873        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6874        try {
6875            // check if target holds top-level <provider> permissions
6876            if (!readMet && pi.readPermission != null && considerUidPermissions
6877                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6878                readMet = true;
6879            }
6880            if (!writeMet && pi.writePermission != null && considerUidPermissions
6881                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6882                writeMet = true;
6883            }
6884
6885            // track if unprotected read/write is allowed; any denied
6886            // <path-permission> below removes this ability
6887            boolean allowDefaultRead = pi.readPermission == null;
6888            boolean allowDefaultWrite = pi.writePermission == null;
6889
6890            // check if target holds any <path-permission> that match uri
6891            final PathPermission[] pps = pi.pathPermissions;
6892            if (pps != null) {
6893                final String path = grantUri.uri.getPath();
6894                int i = pps.length;
6895                while (i > 0 && (!readMet || !writeMet)) {
6896                    i--;
6897                    PathPermission pp = pps[i];
6898                    if (pp.match(path)) {
6899                        if (!readMet) {
6900                            final String pprperm = pp.getReadPermission();
6901                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6902                                    + pprperm + " for " + pp.getPath()
6903                                    + ": match=" + pp.match(path)
6904                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6905                            if (pprperm != null) {
6906                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6907                                        == PERMISSION_GRANTED) {
6908                                    readMet = true;
6909                                } else {
6910                                    allowDefaultRead = false;
6911                                }
6912                            }
6913                        }
6914                        if (!writeMet) {
6915                            final String ppwperm = pp.getWritePermission();
6916                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6917                                    + ppwperm + " for " + pp.getPath()
6918                                    + ": match=" + pp.match(path)
6919                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6920                            if (ppwperm != null) {
6921                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6922                                        == PERMISSION_GRANTED) {
6923                                    writeMet = true;
6924                                } else {
6925                                    allowDefaultWrite = false;
6926                                }
6927                            }
6928                        }
6929                    }
6930                }
6931            }
6932
6933            // grant unprotected <provider> read/write, if not blocked by
6934            // <path-permission> above
6935            if (allowDefaultRead) readMet = true;
6936            if (allowDefaultWrite) writeMet = true;
6937
6938        } catch (RemoteException e) {
6939            return false;
6940        }
6941
6942        return readMet && writeMet;
6943    }
6944
6945    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6946        ProviderInfo pi = null;
6947        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6948        if (cpr != null) {
6949            pi = cpr.info;
6950        } else {
6951            try {
6952                pi = AppGlobals.getPackageManager().resolveContentProvider(
6953                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6954            } catch (RemoteException ex) {
6955            }
6956        }
6957        return pi;
6958    }
6959
6960    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6961        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6962        if (targetUris != null) {
6963            return targetUris.get(grantUri);
6964        }
6965        return null;
6966    }
6967
6968    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6969            String targetPkg, int targetUid, GrantUri grantUri) {
6970        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6971        if (targetUris == null) {
6972            targetUris = Maps.newArrayMap();
6973            mGrantedUriPermissions.put(targetUid, targetUris);
6974        }
6975
6976        UriPermission perm = targetUris.get(grantUri);
6977        if (perm == null) {
6978            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6979            targetUris.put(grantUri, perm);
6980        }
6981
6982        return perm;
6983    }
6984
6985    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6986            final int modeFlags) {
6987        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6988        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6989                : UriPermission.STRENGTH_OWNED;
6990
6991        // Root gets to do everything.
6992        if (uid == 0) {
6993            return true;
6994        }
6995
6996        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6997        if (perms == null) return false;
6998
6999        // First look for exact match
7000        final UriPermission exactPerm = perms.get(grantUri);
7001        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7002            return true;
7003        }
7004
7005        // No exact match, look for prefixes
7006        final int N = perms.size();
7007        for (int i = 0; i < N; i++) {
7008            final UriPermission perm = perms.valueAt(i);
7009            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7010                    && perm.getStrength(modeFlags) >= minStrength) {
7011                return true;
7012            }
7013        }
7014
7015        return false;
7016    }
7017
7018    /**
7019     * @param uri This uri must NOT contain an embedded userId.
7020     * @param userId The userId in which the uri is to be resolved.
7021     */
7022    @Override
7023    public int checkUriPermission(Uri uri, int pid, int uid,
7024            final int modeFlags, int userId, IBinder callerToken) {
7025        enforceNotIsolatedCaller("checkUriPermission");
7026
7027        // Another redirected-binder-call permissions check as in
7028        // {@link checkPermissionWithToken}.
7029        Identity tlsIdentity = sCallerIdentity.get();
7030        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7031            uid = tlsIdentity.uid;
7032            pid = tlsIdentity.pid;
7033        }
7034
7035        // Our own process gets to do everything.
7036        if (pid == MY_PID) {
7037            return PackageManager.PERMISSION_GRANTED;
7038        }
7039        synchronized (this) {
7040            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7041                    ? PackageManager.PERMISSION_GRANTED
7042                    : PackageManager.PERMISSION_DENIED;
7043        }
7044    }
7045
7046    /**
7047     * Check if the targetPkg can be granted permission to access uri by
7048     * the callingUid using the given modeFlags.  Throws a security exception
7049     * if callingUid is not allowed to do this.  Returns the uid of the target
7050     * if the URI permission grant should be performed; returns -1 if it is not
7051     * needed (for example targetPkg already has permission to access the URI).
7052     * If you already know the uid of the target, you can supply it in
7053     * lastTargetUid else set that to -1.
7054     */
7055    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7056            final int modeFlags, int lastTargetUid) {
7057        if (!Intent.isAccessUriMode(modeFlags)) {
7058            return -1;
7059        }
7060
7061        if (targetPkg != null) {
7062            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7063                    "Checking grant " + targetPkg + " permission to " + grantUri);
7064        }
7065
7066        final IPackageManager pm = AppGlobals.getPackageManager();
7067
7068        // If this is not a content: uri, we can't do anything with it.
7069        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7070            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7071                    "Can't grant URI permission for non-content URI: " + grantUri);
7072            return -1;
7073        }
7074
7075        final String authority = grantUri.uri.getAuthority();
7076        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7077        if (pi == null) {
7078            Slog.w(TAG, "No content provider found for permission check: " +
7079                    grantUri.uri.toSafeString());
7080            return -1;
7081        }
7082
7083        int targetUid = lastTargetUid;
7084        if (targetUid < 0 && targetPkg != null) {
7085            try {
7086                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7087                if (targetUid < 0) {
7088                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7089                            "Can't grant URI permission no uid for: " + targetPkg);
7090                    return -1;
7091                }
7092            } catch (RemoteException ex) {
7093                return -1;
7094            }
7095        }
7096
7097        if (targetUid >= 0) {
7098            // First...  does the target actually need this permission?
7099            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7100                // No need to grant the target this permission.
7101                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7102                        "Target " + targetPkg + " already has full permission to " + grantUri);
7103                return -1;
7104            }
7105        } else {
7106            // First...  there is no target package, so can anyone access it?
7107            boolean allowed = pi.exported;
7108            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7109                if (pi.readPermission != null) {
7110                    allowed = false;
7111                }
7112            }
7113            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7114                if (pi.writePermission != null) {
7115                    allowed = false;
7116                }
7117            }
7118            if (allowed) {
7119                return -1;
7120            }
7121        }
7122
7123        /* There is a special cross user grant if:
7124         * - The target is on another user.
7125         * - Apps on the current user can access the uri without any uid permissions.
7126         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7127         * grant uri permissions.
7128         */
7129        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7130                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7131                modeFlags, false /*without considering the uid permissions*/);
7132
7133        // Second...  is the provider allowing granting of URI permissions?
7134        if (!specialCrossUserGrant) {
7135            if (!pi.grantUriPermissions) {
7136                throw new SecurityException("Provider " + pi.packageName
7137                        + "/" + pi.name
7138                        + " does not allow granting of Uri permissions (uri "
7139                        + grantUri + ")");
7140            }
7141            if (pi.uriPermissionPatterns != null) {
7142                final int N = pi.uriPermissionPatterns.length;
7143                boolean allowed = false;
7144                for (int i=0; i<N; i++) {
7145                    if (pi.uriPermissionPatterns[i] != null
7146                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7147                        allowed = true;
7148                        break;
7149                    }
7150                }
7151                if (!allowed) {
7152                    throw new SecurityException("Provider " + pi.packageName
7153                            + "/" + pi.name
7154                            + " does not allow granting of permission to path of Uri "
7155                            + grantUri);
7156                }
7157            }
7158        }
7159
7160        // Third...  does the caller itself have permission to access
7161        // this uri?
7162        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7163            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7164                // Require they hold a strong enough Uri permission
7165                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7166                    throw new SecurityException("Uid " + callingUid
7167                            + " does not have permission to uri " + grantUri);
7168                }
7169            }
7170        }
7171        return targetUid;
7172    }
7173
7174    /**
7175     * @param uri This uri must NOT contain an embedded userId.
7176     * @param userId The userId in which the uri is to be resolved.
7177     */
7178    @Override
7179    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7180            final int modeFlags, int userId) {
7181        enforceNotIsolatedCaller("checkGrantUriPermission");
7182        synchronized(this) {
7183            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7184                    new GrantUri(userId, uri, false), modeFlags, -1);
7185        }
7186    }
7187
7188    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7189            final int modeFlags, UriPermissionOwner owner) {
7190        if (!Intent.isAccessUriMode(modeFlags)) {
7191            return;
7192        }
7193
7194        // So here we are: the caller has the assumed permission
7195        // to the uri, and the target doesn't.  Let's now give this to
7196        // the target.
7197
7198        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7199                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7200
7201        final String authority = grantUri.uri.getAuthority();
7202        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7203        if (pi == null) {
7204            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7205            return;
7206        }
7207
7208        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7209            grantUri.prefix = true;
7210        }
7211        final UriPermission perm = findOrCreateUriPermissionLocked(
7212                pi.packageName, targetPkg, targetUid, grantUri);
7213        perm.grantModes(modeFlags, owner);
7214    }
7215
7216    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7217            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7218        if (targetPkg == null) {
7219            throw new NullPointerException("targetPkg");
7220        }
7221        int targetUid;
7222        final IPackageManager pm = AppGlobals.getPackageManager();
7223        try {
7224            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7225        } catch (RemoteException ex) {
7226            return;
7227        }
7228
7229        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7230                targetUid);
7231        if (targetUid < 0) {
7232            return;
7233        }
7234
7235        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7236                owner);
7237    }
7238
7239    static class NeededUriGrants extends ArrayList<GrantUri> {
7240        final String targetPkg;
7241        final int targetUid;
7242        final int flags;
7243
7244        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7245            this.targetPkg = targetPkg;
7246            this.targetUid = targetUid;
7247            this.flags = flags;
7248        }
7249    }
7250
7251    /**
7252     * Like checkGrantUriPermissionLocked, but takes an Intent.
7253     */
7254    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7255            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7256        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7257                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7258                + " clip=" + (intent != null ? intent.getClipData() : null)
7259                + " from " + intent + "; flags=0x"
7260                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7261
7262        if (targetPkg == null) {
7263            throw new NullPointerException("targetPkg");
7264        }
7265
7266        if (intent == null) {
7267            return null;
7268        }
7269        Uri data = intent.getData();
7270        ClipData clip = intent.getClipData();
7271        if (data == null && clip == null) {
7272            return null;
7273        }
7274        // Default userId for uris in the intent (if they don't specify it themselves)
7275        int contentUserHint = intent.getContentUserHint();
7276        if (contentUserHint == UserHandle.USER_CURRENT) {
7277            contentUserHint = UserHandle.getUserId(callingUid);
7278        }
7279        final IPackageManager pm = AppGlobals.getPackageManager();
7280        int targetUid;
7281        if (needed != null) {
7282            targetUid = needed.targetUid;
7283        } else {
7284            try {
7285                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7286            } catch (RemoteException ex) {
7287                return null;
7288            }
7289            if (targetUid < 0) {
7290                if (DEBUG_URI_PERMISSION) {
7291                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7292                            + " on user " + targetUserId);
7293                }
7294                return null;
7295            }
7296        }
7297        if (data != null) {
7298            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7299            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7300                    targetUid);
7301            if (targetUid > 0) {
7302                if (needed == null) {
7303                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7304                }
7305                needed.add(grantUri);
7306            }
7307        }
7308        if (clip != null) {
7309            for (int i=0; i<clip.getItemCount(); i++) {
7310                Uri uri = clip.getItemAt(i).getUri();
7311                if (uri != null) {
7312                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7313                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7314                            targetUid);
7315                    if (targetUid > 0) {
7316                        if (needed == null) {
7317                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7318                        }
7319                        needed.add(grantUri);
7320                    }
7321                } else {
7322                    Intent clipIntent = clip.getItemAt(i).getIntent();
7323                    if (clipIntent != null) {
7324                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7325                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7326                        if (newNeeded != null) {
7327                            needed = newNeeded;
7328                        }
7329                    }
7330                }
7331            }
7332        }
7333
7334        return needed;
7335    }
7336
7337    /**
7338     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7339     */
7340    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7341            UriPermissionOwner owner) {
7342        if (needed != null) {
7343            for (int i=0; i<needed.size(); i++) {
7344                GrantUri grantUri = needed.get(i);
7345                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7346                        grantUri, needed.flags, owner);
7347            }
7348        }
7349    }
7350
7351    void grantUriPermissionFromIntentLocked(int callingUid,
7352            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7353        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7354                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7355        if (needed == null) {
7356            return;
7357        }
7358
7359        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7360    }
7361
7362    /**
7363     * @param uri This uri must NOT contain an embedded userId.
7364     * @param userId The userId in which the uri is to be resolved.
7365     */
7366    @Override
7367    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7368            final int modeFlags, int userId) {
7369        enforceNotIsolatedCaller("grantUriPermission");
7370        GrantUri grantUri = new GrantUri(userId, uri, false);
7371        synchronized(this) {
7372            final ProcessRecord r = getRecordForAppLocked(caller);
7373            if (r == null) {
7374                throw new SecurityException("Unable to find app for caller "
7375                        + caller
7376                        + " when granting permission to uri " + grantUri);
7377            }
7378            if (targetPkg == null) {
7379                throw new IllegalArgumentException("null target");
7380            }
7381            if (grantUri == null) {
7382                throw new IllegalArgumentException("null uri");
7383            }
7384
7385            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7386                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7387                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7388                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7389
7390            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7391                    UserHandle.getUserId(r.uid));
7392        }
7393    }
7394
7395    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7396        if (perm.modeFlags == 0) {
7397            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7398                    perm.targetUid);
7399            if (perms != null) {
7400                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7401                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7402
7403                perms.remove(perm.uri);
7404                if (perms.isEmpty()) {
7405                    mGrantedUriPermissions.remove(perm.targetUid);
7406                }
7407            }
7408        }
7409    }
7410
7411    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7412        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7413
7414        final IPackageManager pm = AppGlobals.getPackageManager();
7415        final String authority = grantUri.uri.getAuthority();
7416        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7417        if (pi == null) {
7418            Slog.w(TAG, "No content provider found for permission revoke: "
7419                    + grantUri.toSafeString());
7420            return;
7421        }
7422
7423        // Does the caller have this permission on the URI?
7424        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7425            // If they don't have direct access to the URI, then revoke any
7426            // ownerless URI permissions that have been granted to them.
7427            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7428            if (perms != null) {
7429                boolean persistChanged = false;
7430                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7431                    final UriPermission perm = it.next();
7432                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7433                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7434                        if (DEBUG_URI_PERMISSION)
7435                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7436                                    " permission to " + perm.uri);
7437                        persistChanged |= perm.revokeModes(
7438                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7439                        if (perm.modeFlags == 0) {
7440                            it.remove();
7441                        }
7442                    }
7443                }
7444                if (perms.isEmpty()) {
7445                    mGrantedUriPermissions.remove(callingUid);
7446                }
7447                if (persistChanged) {
7448                    schedulePersistUriGrants();
7449                }
7450            }
7451            return;
7452        }
7453
7454        boolean persistChanged = false;
7455
7456        // Go through all of the permissions and remove any that match.
7457        int N = mGrantedUriPermissions.size();
7458        for (int i = 0; i < N; i++) {
7459            final int targetUid = mGrantedUriPermissions.keyAt(i);
7460            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7461
7462            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7463                final UriPermission perm = it.next();
7464                if (perm.uri.sourceUserId == grantUri.sourceUserId
7465                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7466                    if (DEBUG_URI_PERMISSION)
7467                        Slog.v(TAG,
7468                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7469                    persistChanged |= perm.revokeModes(
7470                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7471                    if (perm.modeFlags == 0) {
7472                        it.remove();
7473                    }
7474                }
7475            }
7476
7477            if (perms.isEmpty()) {
7478                mGrantedUriPermissions.remove(targetUid);
7479                N--;
7480                i--;
7481            }
7482        }
7483
7484        if (persistChanged) {
7485            schedulePersistUriGrants();
7486        }
7487    }
7488
7489    /**
7490     * @param uri This uri must NOT contain an embedded userId.
7491     * @param userId The userId in which the uri is to be resolved.
7492     */
7493    @Override
7494    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7495            int userId) {
7496        enforceNotIsolatedCaller("revokeUriPermission");
7497        synchronized(this) {
7498            final ProcessRecord r = getRecordForAppLocked(caller);
7499            if (r == null) {
7500                throw new SecurityException("Unable to find app for caller "
7501                        + caller
7502                        + " when revoking permission to uri " + uri);
7503            }
7504            if (uri == null) {
7505                Slog.w(TAG, "revokeUriPermission: null uri");
7506                return;
7507            }
7508
7509            if (!Intent.isAccessUriMode(modeFlags)) {
7510                return;
7511            }
7512
7513            final IPackageManager pm = AppGlobals.getPackageManager();
7514            final String authority = uri.getAuthority();
7515            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7516            if (pi == null) {
7517                Slog.w(TAG, "No content provider found for permission revoke: "
7518                        + uri.toSafeString());
7519                return;
7520            }
7521
7522            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7523        }
7524    }
7525
7526    /**
7527     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7528     * given package.
7529     *
7530     * @param packageName Package name to match, or {@code null} to apply to all
7531     *            packages.
7532     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7533     *            to all users.
7534     * @param persistable If persistable grants should be removed.
7535     */
7536    private void removeUriPermissionsForPackageLocked(
7537            String packageName, int userHandle, boolean persistable) {
7538        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7539            throw new IllegalArgumentException("Must narrow by either package or user");
7540        }
7541
7542        boolean persistChanged = false;
7543
7544        int N = mGrantedUriPermissions.size();
7545        for (int i = 0; i < N; i++) {
7546            final int targetUid = mGrantedUriPermissions.keyAt(i);
7547            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7548
7549            // Only inspect grants matching user
7550            if (userHandle == UserHandle.USER_ALL
7551                    || userHandle == UserHandle.getUserId(targetUid)) {
7552                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7553                    final UriPermission perm = it.next();
7554
7555                    // Only inspect grants matching package
7556                    if (packageName == null || perm.sourcePkg.equals(packageName)
7557                            || perm.targetPkg.equals(packageName)) {
7558                        persistChanged |= perm.revokeModes(persistable
7559                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7560
7561                        // Only remove when no modes remain; any persisted grants
7562                        // will keep this alive.
7563                        if (perm.modeFlags == 0) {
7564                            it.remove();
7565                        }
7566                    }
7567                }
7568
7569                if (perms.isEmpty()) {
7570                    mGrantedUriPermissions.remove(targetUid);
7571                    N--;
7572                    i--;
7573                }
7574            }
7575        }
7576
7577        if (persistChanged) {
7578            schedulePersistUriGrants();
7579        }
7580    }
7581
7582    @Override
7583    public IBinder newUriPermissionOwner(String name) {
7584        enforceNotIsolatedCaller("newUriPermissionOwner");
7585        synchronized(this) {
7586            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7587            return owner.getExternalTokenLocked();
7588        }
7589    }
7590
7591    /**
7592     * @param uri This uri must NOT contain an embedded userId.
7593     * @param sourceUserId The userId in which the uri is to be resolved.
7594     * @param targetUserId The userId of the app that receives the grant.
7595     */
7596    @Override
7597    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7598            final int modeFlags, int sourceUserId, int targetUserId) {
7599        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7600                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7601        synchronized(this) {
7602            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7603            if (owner == null) {
7604                throw new IllegalArgumentException("Unknown owner: " + token);
7605            }
7606            if (fromUid != Binder.getCallingUid()) {
7607                if (Binder.getCallingUid() != Process.myUid()) {
7608                    // Only system code can grant URI permissions on behalf
7609                    // of other users.
7610                    throw new SecurityException("nice try");
7611                }
7612            }
7613            if (targetPkg == null) {
7614                throw new IllegalArgumentException("null target");
7615            }
7616            if (uri == null) {
7617                throw new IllegalArgumentException("null uri");
7618            }
7619
7620            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7621                    modeFlags, owner, targetUserId);
7622        }
7623    }
7624
7625    /**
7626     * @param uri This uri must NOT contain an embedded userId.
7627     * @param userId The userId in which the uri is to be resolved.
7628     */
7629    @Override
7630    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7631        synchronized(this) {
7632            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7633            if (owner == null) {
7634                throw new IllegalArgumentException("Unknown owner: " + token);
7635            }
7636
7637            if (uri == null) {
7638                owner.removeUriPermissionsLocked(mode);
7639            } else {
7640                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7641            }
7642        }
7643    }
7644
7645    private void schedulePersistUriGrants() {
7646        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7647            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7648                    10 * DateUtils.SECOND_IN_MILLIS);
7649        }
7650    }
7651
7652    private void writeGrantedUriPermissions() {
7653        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7654
7655        // Snapshot permissions so we can persist without lock
7656        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7657        synchronized (this) {
7658            final int size = mGrantedUriPermissions.size();
7659            for (int i = 0; i < size; i++) {
7660                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7661                for (UriPermission perm : perms.values()) {
7662                    if (perm.persistedModeFlags != 0) {
7663                        persist.add(perm.snapshot());
7664                    }
7665                }
7666            }
7667        }
7668
7669        FileOutputStream fos = null;
7670        try {
7671            fos = mGrantFile.startWrite();
7672
7673            XmlSerializer out = new FastXmlSerializer();
7674            out.setOutput(fos, "utf-8");
7675            out.startDocument(null, true);
7676            out.startTag(null, TAG_URI_GRANTS);
7677            for (UriPermission.Snapshot perm : persist) {
7678                out.startTag(null, TAG_URI_GRANT);
7679                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7680                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7681                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7682                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7683                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7684                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7685                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7686                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7687                out.endTag(null, TAG_URI_GRANT);
7688            }
7689            out.endTag(null, TAG_URI_GRANTS);
7690            out.endDocument();
7691
7692            mGrantFile.finishWrite(fos);
7693        } catch (IOException e) {
7694            if (fos != null) {
7695                mGrantFile.failWrite(fos);
7696            }
7697        }
7698    }
7699
7700    private void readGrantedUriPermissionsLocked() {
7701        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7702
7703        final long now = System.currentTimeMillis();
7704
7705        FileInputStream fis = null;
7706        try {
7707            fis = mGrantFile.openRead();
7708            final XmlPullParser in = Xml.newPullParser();
7709            in.setInput(fis, null);
7710
7711            int type;
7712            while ((type = in.next()) != END_DOCUMENT) {
7713                final String tag = in.getName();
7714                if (type == START_TAG) {
7715                    if (TAG_URI_GRANT.equals(tag)) {
7716                        final int sourceUserId;
7717                        final int targetUserId;
7718                        final int userHandle = readIntAttribute(in,
7719                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7720                        if (userHandle != UserHandle.USER_NULL) {
7721                            // For backwards compatibility.
7722                            sourceUserId = userHandle;
7723                            targetUserId = userHandle;
7724                        } else {
7725                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7726                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7727                        }
7728                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7729                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7730                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7731                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7732                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7733                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7734
7735                        // Sanity check that provider still belongs to source package
7736                        final ProviderInfo pi = getProviderInfoLocked(
7737                                uri.getAuthority(), sourceUserId);
7738                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7739                            int targetUid = -1;
7740                            try {
7741                                targetUid = AppGlobals.getPackageManager()
7742                                        .getPackageUid(targetPkg, targetUserId);
7743                            } catch (RemoteException e) {
7744                            }
7745                            if (targetUid != -1) {
7746                                final UriPermission perm = findOrCreateUriPermissionLocked(
7747                                        sourcePkg, targetPkg, targetUid,
7748                                        new GrantUri(sourceUserId, uri, prefix));
7749                                perm.initPersistedModes(modeFlags, createdTime);
7750                            }
7751                        } else {
7752                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7753                                    + " but instead found " + pi);
7754                        }
7755                    }
7756                }
7757            }
7758        } catch (FileNotFoundException e) {
7759            // Missing grants is okay
7760        } catch (IOException e) {
7761            Slog.wtf(TAG, "Failed reading Uri grants", e);
7762        } catch (XmlPullParserException e) {
7763            Slog.wtf(TAG, "Failed reading Uri grants", e);
7764        } finally {
7765            IoUtils.closeQuietly(fis);
7766        }
7767    }
7768
7769    /**
7770     * @param uri This uri must NOT contain an embedded userId.
7771     * @param userId The userId in which the uri is to be resolved.
7772     */
7773    @Override
7774    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7775        enforceNotIsolatedCaller("takePersistableUriPermission");
7776
7777        Preconditions.checkFlagsArgument(modeFlags,
7778                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7779
7780        synchronized (this) {
7781            final int callingUid = Binder.getCallingUid();
7782            boolean persistChanged = false;
7783            GrantUri grantUri = new GrantUri(userId, uri, false);
7784
7785            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7786                    new GrantUri(userId, uri, false));
7787            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7788                    new GrantUri(userId, uri, true));
7789
7790            final boolean exactValid = (exactPerm != null)
7791                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7792            final boolean prefixValid = (prefixPerm != null)
7793                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7794
7795            if (!(exactValid || prefixValid)) {
7796                throw new SecurityException("No persistable permission grants found for UID "
7797                        + callingUid + " and Uri " + grantUri.toSafeString());
7798            }
7799
7800            if (exactValid) {
7801                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7802            }
7803            if (prefixValid) {
7804                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7805            }
7806
7807            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7808
7809            if (persistChanged) {
7810                schedulePersistUriGrants();
7811            }
7812        }
7813    }
7814
7815    /**
7816     * @param uri This uri must NOT contain an embedded userId.
7817     * @param userId The userId in which the uri is to be resolved.
7818     */
7819    @Override
7820    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7821        enforceNotIsolatedCaller("releasePersistableUriPermission");
7822
7823        Preconditions.checkFlagsArgument(modeFlags,
7824                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7825
7826        synchronized (this) {
7827            final int callingUid = Binder.getCallingUid();
7828            boolean persistChanged = false;
7829
7830            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7831                    new GrantUri(userId, uri, false));
7832            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7833                    new GrantUri(userId, uri, true));
7834            if (exactPerm == null && prefixPerm == null) {
7835                throw new SecurityException("No permission grants found for UID " + callingUid
7836                        + " and Uri " + uri.toSafeString());
7837            }
7838
7839            if (exactPerm != null) {
7840                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7841                removeUriPermissionIfNeededLocked(exactPerm);
7842            }
7843            if (prefixPerm != null) {
7844                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7845                removeUriPermissionIfNeededLocked(prefixPerm);
7846            }
7847
7848            if (persistChanged) {
7849                schedulePersistUriGrants();
7850            }
7851        }
7852    }
7853
7854    /**
7855     * Prune any older {@link UriPermission} for the given UID until outstanding
7856     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7857     *
7858     * @return if any mutations occured that require persisting.
7859     */
7860    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7861        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7862        if (perms == null) return false;
7863        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7864
7865        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7866        for (UriPermission perm : perms.values()) {
7867            if (perm.persistedModeFlags != 0) {
7868                persisted.add(perm);
7869            }
7870        }
7871
7872        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7873        if (trimCount <= 0) return false;
7874
7875        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7876        for (int i = 0; i < trimCount; i++) {
7877            final UriPermission perm = persisted.get(i);
7878
7879            if (DEBUG_URI_PERMISSION) {
7880                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7881            }
7882
7883            perm.releasePersistableModes(~0);
7884            removeUriPermissionIfNeededLocked(perm);
7885        }
7886
7887        return true;
7888    }
7889
7890    @Override
7891    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7892            String packageName, boolean incoming) {
7893        enforceNotIsolatedCaller("getPersistedUriPermissions");
7894        Preconditions.checkNotNull(packageName, "packageName");
7895
7896        final int callingUid = Binder.getCallingUid();
7897        final IPackageManager pm = AppGlobals.getPackageManager();
7898        try {
7899            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7900            if (packageUid != callingUid) {
7901                throw new SecurityException(
7902                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7903            }
7904        } catch (RemoteException e) {
7905            throw new SecurityException("Failed to verify package name ownership");
7906        }
7907
7908        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7909        synchronized (this) {
7910            if (incoming) {
7911                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7912                        callingUid);
7913                if (perms == null) {
7914                    Slog.w(TAG, "No permission grants found for " + packageName);
7915                } else {
7916                    for (UriPermission perm : perms.values()) {
7917                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7918                            result.add(perm.buildPersistedPublicApiObject());
7919                        }
7920                    }
7921                }
7922            } else {
7923                final int size = mGrantedUriPermissions.size();
7924                for (int i = 0; i < size; i++) {
7925                    final ArrayMap<GrantUri, UriPermission> perms =
7926                            mGrantedUriPermissions.valueAt(i);
7927                    for (UriPermission perm : perms.values()) {
7928                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7929                            result.add(perm.buildPersistedPublicApiObject());
7930                        }
7931                    }
7932                }
7933            }
7934        }
7935        return new ParceledListSlice<android.content.UriPermission>(result);
7936    }
7937
7938    @Override
7939    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7940        synchronized (this) {
7941            ProcessRecord app =
7942                who != null ? getRecordForAppLocked(who) : null;
7943            if (app == null) return;
7944
7945            Message msg = Message.obtain();
7946            msg.what = WAIT_FOR_DEBUGGER_MSG;
7947            msg.obj = app;
7948            msg.arg1 = waiting ? 1 : 0;
7949            mHandler.sendMessage(msg);
7950        }
7951    }
7952
7953    @Override
7954    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7955        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7956        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7957        outInfo.availMem = Process.getFreeMemory();
7958        outInfo.totalMem = Process.getTotalMemory();
7959        outInfo.threshold = homeAppMem;
7960        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7961        outInfo.hiddenAppThreshold = cachedAppMem;
7962        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7963                ProcessList.SERVICE_ADJ);
7964        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7965                ProcessList.VISIBLE_APP_ADJ);
7966        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7967                ProcessList.FOREGROUND_APP_ADJ);
7968    }
7969
7970    // =========================================================
7971    // TASK MANAGEMENT
7972    // =========================================================
7973
7974    @Override
7975    public List<IAppTask> getAppTasks(String callingPackage) {
7976        int callingUid = Binder.getCallingUid();
7977        long ident = Binder.clearCallingIdentity();
7978
7979        synchronized(this) {
7980            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7981            try {
7982                if (localLOGV) Slog.v(TAG, "getAppTasks");
7983
7984                final int N = mRecentTasks.size();
7985                for (int i = 0; i < N; i++) {
7986                    TaskRecord tr = mRecentTasks.get(i);
7987                    // Skip tasks that do not match the caller.  We don't need to verify
7988                    // callingPackage, because we are also limiting to callingUid and know
7989                    // that will limit to the correct security sandbox.
7990                    if (tr.effectiveUid != callingUid) {
7991                        continue;
7992                    }
7993                    Intent intent = tr.getBaseIntent();
7994                    if (intent == null ||
7995                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7996                        continue;
7997                    }
7998                    ActivityManager.RecentTaskInfo taskInfo =
7999                            createRecentTaskInfoFromTaskRecord(tr);
8000                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8001                    list.add(taskImpl);
8002                }
8003            } finally {
8004                Binder.restoreCallingIdentity(ident);
8005            }
8006            return list;
8007        }
8008    }
8009
8010    @Override
8011    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8012        final int callingUid = Binder.getCallingUid();
8013        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8014
8015        synchronized(this) {
8016            if (localLOGV) Slog.v(
8017                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8018
8019            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8020                    callingUid);
8021
8022            // TODO: Improve with MRU list from all ActivityStacks.
8023            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8024        }
8025
8026        return list;
8027    }
8028
8029    /**
8030     * Creates a new RecentTaskInfo from a TaskRecord.
8031     */
8032    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8033        // Update the task description to reflect any changes in the task stack
8034        tr.updateTaskDescription();
8035
8036        // Compose the recent task info
8037        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8038        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8039        rti.persistentId = tr.taskId;
8040        rti.baseIntent = new Intent(tr.getBaseIntent());
8041        rti.origActivity = tr.origActivity;
8042        rti.description = tr.lastDescription;
8043        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8044        rti.userId = tr.userId;
8045        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8046        rti.firstActiveTime = tr.firstActiveTime;
8047        rti.lastActiveTime = tr.lastActiveTime;
8048        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8049        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8050        return rti;
8051    }
8052
8053    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8054        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8055                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8056        if (!allowed) {
8057            if (checkPermission(android.Manifest.permission.GET_TASKS,
8058                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8059                // Temporary compatibility: some existing apps on the system image may
8060                // still be requesting the old permission and not switched to the new
8061                // one; if so, we'll still allow them full access.  This means we need
8062                // to see if they are holding the old permission and are a system app.
8063                try {
8064                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8065                        allowed = true;
8066                        Slog.w(TAG, caller + ": caller " + callingUid
8067                                + " is using old GET_TASKS but privileged; allowing");
8068                    }
8069                } catch (RemoteException e) {
8070                }
8071            }
8072        }
8073        if (!allowed) {
8074            Slog.w(TAG, caller + ": caller " + callingUid
8075                    + " does not hold GET_TASKS; limiting output");
8076        }
8077        return allowed;
8078    }
8079
8080    @Override
8081    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8082        final int callingUid = Binder.getCallingUid();
8083        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8084                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8085
8086        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8087        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8088        synchronized (this) {
8089            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8090                    callingUid);
8091            final boolean detailed = checkCallingPermission(
8092                    android.Manifest.permission.GET_DETAILED_TASKS)
8093                    == PackageManager.PERMISSION_GRANTED;
8094
8095            final int N = mRecentTasks.size();
8096            ArrayList<ActivityManager.RecentTaskInfo> res
8097                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8098                            maxNum < N ? maxNum : N);
8099
8100            final Set<Integer> includedUsers;
8101            if (includeProfiles) {
8102                includedUsers = getProfileIdsLocked(userId);
8103            } else {
8104                includedUsers = new HashSet<Integer>();
8105            }
8106            includedUsers.add(Integer.valueOf(userId));
8107
8108            for (int i=0; i<N && maxNum > 0; i++) {
8109                TaskRecord tr = mRecentTasks.get(i);
8110                // Only add calling user or related users recent tasks
8111                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8112                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8113                    continue;
8114                }
8115
8116                // Return the entry if desired by the caller.  We always return
8117                // the first entry, because callers always expect this to be the
8118                // foreground app.  We may filter others if the caller has
8119                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8120                // we should exclude the entry.
8121
8122                if (i == 0
8123                        || withExcluded
8124                        || (tr.intent == null)
8125                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8126                                == 0)) {
8127                    if (!allowed) {
8128                        // If the caller doesn't have the GET_TASKS permission, then only
8129                        // allow them to see a small subset of tasks -- their own and home.
8130                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8131                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8132                            continue;
8133                        }
8134                    }
8135                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8136                        if (tr.stack != null && tr.stack.isHomeStack()) {
8137                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8138                            continue;
8139                        }
8140                    }
8141                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8142                        // Don't include auto remove tasks that are finished or finishing.
8143                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8144                                + tr);
8145                        continue;
8146                    }
8147                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8148                            && !tr.isAvailable) {
8149                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8150                        continue;
8151                    }
8152
8153                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8154                    if (!detailed) {
8155                        rti.baseIntent.replaceExtras((Bundle)null);
8156                    }
8157
8158                    res.add(rti);
8159                    maxNum--;
8160                }
8161            }
8162            return res;
8163        }
8164    }
8165
8166    private TaskRecord taskForIdLocked(int id) {
8167        final TaskRecord task = recentTaskForIdLocked(id);
8168        if (task != null) {
8169            return task;
8170        }
8171
8172        // Don't give up. Sometimes it just hasn't made it to recents yet.
8173        return mStackSupervisor.anyTaskForIdLocked(id);
8174    }
8175
8176    private TaskRecord recentTaskForIdLocked(int id) {
8177        final int N = mRecentTasks.size();
8178            for (int i=0; i<N; i++) {
8179                TaskRecord tr = mRecentTasks.get(i);
8180                if (tr.taskId == id) {
8181                    return tr;
8182                }
8183            }
8184            return null;
8185    }
8186
8187    @Override
8188    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8189        synchronized (this) {
8190            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8191                    "getTaskThumbnail()");
8192            TaskRecord tr = recentTaskForIdLocked(id);
8193            if (tr != null) {
8194                return tr.getTaskThumbnailLocked();
8195            }
8196        }
8197        return null;
8198    }
8199
8200    @Override
8201    public int addAppTask(IBinder activityToken, Intent intent,
8202            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8203        final int callingUid = Binder.getCallingUid();
8204        final long callingIdent = Binder.clearCallingIdentity();
8205
8206        try {
8207            synchronized (this) {
8208                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8209                if (r == null) {
8210                    throw new IllegalArgumentException("Activity does not exist; token="
8211                            + activityToken);
8212                }
8213                ComponentName comp = intent.getComponent();
8214                if (comp == null) {
8215                    throw new IllegalArgumentException("Intent " + intent
8216                            + " must specify explicit component");
8217                }
8218                if (thumbnail.getWidth() != mThumbnailWidth
8219                        || thumbnail.getHeight() != mThumbnailHeight) {
8220                    throw new IllegalArgumentException("Bad thumbnail size: got "
8221                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8222                            + mThumbnailWidth + "x" + mThumbnailHeight);
8223                }
8224                if (intent.getSelector() != null) {
8225                    intent.setSelector(null);
8226                }
8227                if (intent.getSourceBounds() != null) {
8228                    intent.setSourceBounds(null);
8229                }
8230                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8231                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8232                        // The caller has added this as an auto-remove task...  that makes no
8233                        // sense, so turn off auto-remove.
8234                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8235                    }
8236                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8237                    // Must be a new task.
8238                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8239                }
8240                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8241                    mLastAddedTaskActivity = null;
8242                }
8243                ActivityInfo ainfo = mLastAddedTaskActivity;
8244                if (ainfo == null) {
8245                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8246                            comp, 0, UserHandle.getUserId(callingUid));
8247                    if (ainfo.applicationInfo.uid != callingUid) {
8248                        throw new SecurityException(
8249                                "Can't add task for another application: target uid="
8250                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8251                    }
8252                }
8253
8254                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8255                        intent, description);
8256
8257                int trimIdx = trimRecentsForTaskLocked(task, false);
8258                if (trimIdx >= 0) {
8259                    // If this would have caused a trim, then we'll abort because that
8260                    // means it would be added at the end of the list but then just removed.
8261                    return -1;
8262                }
8263
8264                final int N = mRecentTasks.size();
8265                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8266                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8267                    tr.removedFromRecents();
8268                }
8269
8270                task.inRecents = true;
8271                mRecentTasks.add(task);
8272                r.task.stack.addTask(task, false, false);
8273
8274                task.setLastThumbnail(thumbnail);
8275                task.freeLastThumbnail();
8276
8277                return task.taskId;
8278            }
8279        } finally {
8280            Binder.restoreCallingIdentity(callingIdent);
8281        }
8282    }
8283
8284    @Override
8285    public Point getAppTaskThumbnailSize() {
8286        synchronized (this) {
8287            return new Point(mThumbnailWidth,  mThumbnailHeight);
8288        }
8289    }
8290
8291    @Override
8292    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8293        synchronized (this) {
8294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8295            if (r != null) {
8296                r.setTaskDescription(td);
8297                r.task.updateTaskDescription();
8298            }
8299        }
8300    }
8301
8302    @Override
8303    public Bitmap getTaskDescriptionIcon(String filename) {
8304        if (!FileUtils.isValidExtFilename(filename)
8305                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8306            throw new IllegalArgumentException("Bad filename: " + filename);
8307        }
8308        return mTaskPersister.getTaskDescriptionIcon(filename);
8309    }
8310
8311    @Override
8312    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8313            throws RemoteException {
8314        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8315                opts.getCustomInPlaceResId() == 0) {
8316            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8317                    "with valid animation");
8318        }
8319        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8320        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8321                opts.getCustomInPlaceResId());
8322        mWindowManager.executeAppTransition();
8323    }
8324
8325    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8326        mRecentTasks.remove(tr);
8327        tr.removedFromRecents();
8328        ComponentName component = tr.getBaseIntent().getComponent();
8329        if (component == null) {
8330            Slog.w(TAG, "No component for base intent of task: " + tr);
8331            return;
8332        }
8333
8334        if (!killProcess) {
8335            return;
8336        }
8337
8338        // Determine if the process(es) for this task should be killed.
8339        final String pkg = component.getPackageName();
8340        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8341        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8342        for (int i = 0; i < pmap.size(); i++) {
8343
8344            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8345            for (int j = 0; j < uids.size(); j++) {
8346                ProcessRecord proc = uids.valueAt(j);
8347                if (proc.userId != tr.userId) {
8348                    // Don't kill process for a different user.
8349                    continue;
8350                }
8351                if (proc == mHomeProcess) {
8352                    // Don't kill the home process along with tasks from the same package.
8353                    continue;
8354                }
8355                if (!proc.pkgList.containsKey(pkg)) {
8356                    // Don't kill process that is not associated with this task.
8357                    continue;
8358                }
8359
8360                for (int k = 0; k < proc.activities.size(); k++) {
8361                    TaskRecord otherTask = proc.activities.get(k).task;
8362                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8363                        // Don't kill process(es) that has an activity in a different task that is
8364                        // also in recents.
8365                        return;
8366                    }
8367                }
8368
8369                // Add process to kill list.
8370                procsToKill.add(proc);
8371            }
8372        }
8373
8374        // Find any running services associated with this app and stop if needed.
8375        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8376
8377        // Kill the running processes.
8378        for (int i = 0; i < procsToKill.size(); i++) {
8379            ProcessRecord pr = procsToKill.get(i);
8380            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8381                pr.kill("remove task", true);
8382            } else {
8383                pr.waitingToKill = "remove task";
8384            }
8385        }
8386    }
8387
8388    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8389        // Remove all tasks with activities in the specified package from the list of recent tasks
8390        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8391            TaskRecord tr = mRecentTasks.get(i);
8392            if (tr.userId != userId) continue;
8393
8394            ComponentName cn = tr.intent.getComponent();
8395            if (cn != null && cn.getPackageName().equals(packageName)) {
8396                // If the package name matches, remove the task.
8397                removeTaskByIdLocked(tr.taskId, true);
8398            }
8399        }
8400    }
8401
8402    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8403        final IPackageManager pm = AppGlobals.getPackageManager();
8404        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8405
8406        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8407            TaskRecord tr = mRecentTasks.get(i);
8408            if (tr.userId != userId) continue;
8409
8410            ComponentName cn = tr.intent.getComponent();
8411            if (cn != null && cn.getPackageName().equals(packageName)) {
8412                // Skip if component still exists in the package.
8413                if (componentsKnownToExist.contains(cn)) continue;
8414
8415                try {
8416                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8417                    if (info != null) {
8418                        componentsKnownToExist.add(cn);
8419                    } else {
8420                        removeTaskByIdLocked(tr.taskId, false);
8421                    }
8422                } catch (RemoteException e) {
8423                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8424                }
8425            }
8426        }
8427    }
8428
8429    /**
8430     * Removes the task with the specified task id.
8431     *
8432     * @param taskId Identifier of the task to be removed.
8433     * @param killProcess Kill any process associated with the task if possible.
8434     * @return Returns true if the given task was found and removed.
8435     */
8436    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8437        TaskRecord tr = taskForIdLocked(taskId);
8438        if (tr != null) {
8439            tr.removeTaskActivitiesLocked();
8440            cleanUpRemovedTaskLocked(tr, killProcess);
8441            if (tr.isPersistable) {
8442                notifyTaskPersisterLocked(null, true);
8443            }
8444            return true;
8445        }
8446        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8447        return false;
8448    }
8449
8450    @Override
8451    public boolean removeTask(int taskId) {
8452        synchronized (this) {
8453            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8454                    "removeTask()");
8455            long ident = Binder.clearCallingIdentity();
8456            try {
8457                return removeTaskByIdLocked(taskId, true);
8458            } finally {
8459                Binder.restoreCallingIdentity(ident);
8460            }
8461        }
8462    }
8463
8464    /**
8465     * TODO: Add mController hook
8466     */
8467    @Override
8468    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8469        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8470                "moveTaskToFront()");
8471
8472        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8473        synchronized(this) {
8474            moveTaskToFrontLocked(taskId, flags, options);
8475        }
8476    }
8477
8478    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8479        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8480                Binder.getCallingUid(), -1, -1, "Task to front")) {
8481            ActivityOptions.abort(options);
8482            return;
8483        }
8484        final long origId = Binder.clearCallingIdentity();
8485        try {
8486            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8487            if (task == null) {
8488                Slog.d(TAG, "Could not find task for id: "+ taskId);
8489                return;
8490            }
8491            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8492                mStackSupervisor.showLockTaskToast();
8493                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8494                return;
8495            }
8496            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8497            if (prev != null && prev.isRecentsActivity()) {
8498                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8499            }
8500            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8501        } finally {
8502            Binder.restoreCallingIdentity(origId);
8503        }
8504        ActivityOptions.abort(options);
8505    }
8506
8507    @Override
8508    public void moveTaskToBack(int taskId) {
8509        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8510                "moveTaskToBack()");
8511
8512        synchronized(this) {
8513            TaskRecord tr = taskForIdLocked(taskId);
8514            if (tr != null) {
8515                if (tr == mStackSupervisor.mLockTaskModeTask) {
8516                    mStackSupervisor.showLockTaskToast();
8517                    return;
8518                }
8519                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8520                ActivityStack stack = tr.stack;
8521                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8522                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8523                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8524                        return;
8525                    }
8526                }
8527                final long origId = Binder.clearCallingIdentity();
8528                try {
8529                    stack.moveTaskToBackLocked(taskId, null);
8530                } finally {
8531                    Binder.restoreCallingIdentity(origId);
8532                }
8533            }
8534        }
8535    }
8536
8537    /**
8538     * Moves an activity, and all of the other activities within the same task, to the bottom
8539     * of the history stack.  The activity's order within the task is unchanged.
8540     *
8541     * @param token A reference to the activity we wish to move
8542     * @param nonRoot If false then this only works if the activity is the root
8543     *                of a task; if true it will work for any activity in a task.
8544     * @return Returns true if the move completed, false if not.
8545     */
8546    @Override
8547    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8548        enforceNotIsolatedCaller("moveActivityTaskToBack");
8549        synchronized(this) {
8550            final long origId = Binder.clearCallingIdentity();
8551            try {
8552                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8553                if (taskId >= 0) {
8554                    if ((mStackSupervisor.mLockTaskModeTask != null)
8555                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8556                        mStackSupervisor.showLockTaskToast();
8557                        return false;
8558                    }
8559                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8560                }
8561            } finally {
8562                Binder.restoreCallingIdentity(origId);
8563            }
8564        }
8565        return false;
8566    }
8567
8568    @Override
8569    public void moveTaskBackwards(int task) {
8570        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8571                "moveTaskBackwards()");
8572
8573        synchronized(this) {
8574            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8575                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8576                return;
8577            }
8578            final long origId = Binder.clearCallingIdentity();
8579            moveTaskBackwardsLocked(task);
8580            Binder.restoreCallingIdentity(origId);
8581        }
8582    }
8583
8584    private final void moveTaskBackwardsLocked(int task) {
8585        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8586    }
8587
8588    @Override
8589    public IBinder getHomeActivityToken() throws RemoteException {
8590        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8591                "getHomeActivityToken()");
8592        synchronized (this) {
8593            return mStackSupervisor.getHomeActivityToken();
8594        }
8595    }
8596
8597    @Override
8598    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8599            IActivityContainerCallback callback) throws RemoteException {
8600        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8601                "createActivityContainer()");
8602        synchronized (this) {
8603            if (parentActivityToken == null) {
8604                throw new IllegalArgumentException("parent token must not be null");
8605            }
8606            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8607            if (r == null) {
8608                return null;
8609            }
8610            if (callback == null) {
8611                throw new IllegalArgumentException("callback must not be null");
8612            }
8613            return mStackSupervisor.createActivityContainer(r, callback);
8614        }
8615    }
8616
8617    @Override
8618    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8619        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8620                "deleteActivityContainer()");
8621        synchronized (this) {
8622            mStackSupervisor.deleteActivityContainer(container);
8623        }
8624    }
8625
8626    @Override
8627    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8628            throws RemoteException {
8629        synchronized (this) {
8630            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8631            if (stack != null) {
8632                return stack.mActivityContainer;
8633            }
8634            return null;
8635        }
8636    }
8637
8638    @Override
8639    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8640        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8641                "moveTaskToStack()");
8642        if (stackId == HOME_STACK_ID) {
8643            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8644                    new RuntimeException("here").fillInStackTrace());
8645        }
8646        synchronized (this) {
8647            long ident = Binder.clearCallingIdentity();
8648            try {
8649                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8650                        + stackId + " toTop=" + toTop);
8651                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8652            } finally {
8653                Binder.restoreCallingIdentity(ident);
8654            }
8655        }
8656    }
8657
8658    @Override
8659    public void resizeStack(int stackBoxId, Rect bounds) {
8660        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8661                "resizeStackBox()");
8662        long ident = Binder.clearCallingIdentity();
8663        try {
8664            mWindowManager.resizeStack(stackBoxId, bounds);
8665        } finally {
8666            Binder.restoreCallingIdentity(ident);
8667        }
8668    }
8669
8670    @Override
8671    public List<StackInfo> getAllStackInfos() {
8672        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8673                "getAllStackInfos()");
8674        long ident = Binder.clearCallingIdentity();
8675        try {
8676            synchronized (this) {
8677                return mStackSupervisor.getAllStackInfosLocked();
8678            }
8679        } finally {
8680            Binder.restoreCallingIdentity(ident);
8681        }
8682    }
8683
8684    @Override
8685    public StackInfo getStackInfo(int stackId) {
8686        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8687                "getStackInfo()");
8688        long ident = Binder.clearCallingIdentity();
8689        try {
8690            synchronized (this) {
8691                return mStackSupervisor.getStackInfoLocked(stackId);
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(ident);
8695        }
8696    }
8697
8698    @Override
8699    public boolean isInHomeStack(int taskId) {
8700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                "getStackInfo()");
8702        long ident = Binder.clearCallingIdentity();
8703        try {
8704            synchronized (this) {
8705                TaskRecord tr = taskForIdLocked(taskId);
8706                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8707            }
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8715        synchronized(this) {
8716            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8717        }
8718    }
8719
8720    private boolean isLockTaskAuthorized(String pkg) {
8721        final DevicePolicyManager dpm = (DevicePolicyManager)
8722                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8723        try {
8724            int uid = mContext.getPackageManager().getPackageUid(pkg,
8725                    Binder.getCallingUserHandle().getIdentifier());
8726            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8727        } catch (NameNotFoundException e) {
8728            return false;
8729        }
8730    }
8731
8732    void startLockTaskMode(TaskRecord task) {
8733        final String pkg;
8734        synchronized (this) {
8735            pkg = task.intent.getComponent().getPackageName();
8736        }
8737        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8738        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8739            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8740                    StatusBarManagerInternal.class);
8741            if (statusBarManager != null) {
8742                statusBarManager.showScreenPinningRequest();
8743            }
8744            return;
8745        }
8746        long ident = Binder.clearCallingIdentity();
8747        try {
8748            synchronized (this) {
8749                // Since we lost lock on task, make sure it is still there.
8750                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8751                if (task != null) {
8752                    if (!isSystemInitiated
8753                            && ((mStackSupervisor.getFocusedStack() == null)
8754                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8755                        throw new IllegalArgumentException("Invalid task, not in foreground");
8756                    }
8757                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8758                }
8759            }
8760        } finally {
8761            Binder.restoreCallingIdentity(ident);
8762        }
8763    }
8764
8765    @Override
8766    public void startLockTaskMode(int taskId) {
8767        final TaskRecord task;
8768        long ident = Binder.clearCallingIdentity();
8769        try {
8770            synchronized (this) {
8771                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8772            }
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776        if (task != null) {
8777            startLockTaskMode(task);
8778        }
8779    }
8780
8781    @Override
8782    public void startLockTaskMode(IBinder token) {
8783        final TaskRecord task;
8784        long ident = Binder.clearCallingIdentity();
8785        try {
8786            synchronized (this) {
8787                final ActivityRecord r = ActivityRecord.forToken(token);
8788                if (r == null) {
8789                    return;
8790                }
8791                task = r.task;
8792            }
8793        } finally {
8794            Binder.restoreCallingIdentity(ident);
8795        }
8796        if (task != null) {
8797            startLockTaskMode(task);
8798        }
8799    }
8800
8801    @Override
8802    public void startLockTaskModeOnCurrent() throws RemoteException {
8803        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8804                "startLockTaskModeOnCurrent");
8805        long ident = Binder.clearCallingIdentity();
8806        try {
8807            ActivityRecord r = null;
8808            synchronized (this) {
8809                r = mStackSupervisor.topRunningActivityLocked();
8810            }
8811            startLockTaskMode(r.task);
8812        } finally {
8813            Binder.restoreCallingIdentity(ident);
8814        }
8815    }
8816
8817    @Override
8818    public void stopLockTaskMode() {
8819        // Verify that the user matches the package of the intent for the TaskRecord
8820        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8821        // and stopLockTaskMode.
8822        final int callingUid = Binder.getCallingUid();
8823        if (callingUid != Process.SYSTEM_UID) {
8824            try {
8825                String pkg =
8826                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8827                int uid = mContext.getPackageManager().getPackageUid(pkg,
8828                        Binder.getCallingUserHandle().getIdentifier());
8829                if (uid != callingUid) {
8830                    throw new SecurityException("Invalid uid, expected " + uid);
8831                }
8832            } catch (NameNotFoundException e) {
8833                Log.d(TAG, "stopLockTaskMode " + e);
8834                return;
8835            }
8836        }
8837        long ident = Binder.clearCallingIdentity();
8838        try {
8839            Log.d(TAG, "stopLockTaskMode");
8840            // Stop lock task
8841            synchronized (this) {
8842                mStackSupervisor.setLockTaskModeLocked(null, false);
8843            }
8844        } finally {
8845            Binder.restoreCallingIdentity(ident);
8846        }
8847    }
8848
8849    @Override
8850    public void stopLockTaskModeOnCurrent() throws RemoteException {
8851        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8852                "stopLockTaskModeOnCurrent");
8853        long ident = Binder.clearCallingIdentity();
8854        try {
8855            stopLockTaskMode();
8856        } finally {
8857            Binder.restoreCallingIdentity(ident);
8858        }
8859    }
8860
8861    @Override
8862    public boolean isInLockTaskMode() {
8863        synchronized (this) {
8864            return mStackSupervisor.isInLockTaskMode();
8865        }
8866    }
8867
8868    // =========================================================
8869    // CONTENT PROVIDERS
8870    // =========================================================
8871
8872    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8873        List<ProviderInfo> providers = null;
8874        try {
8875            providers = AppGlobals.getPackageManager().
8876                queryContentProviders(app.processName, app.uid,
8877                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8878        } catch (RemoteException ex) {
8879        }
8880        if (DEBUG_MU)
8881            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8882        int userId = app.userId;
8883        if (providers != null) {
8884            int N = providers.size();
8885            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8886            for (int i=0; i<N; i++) {
8887                ProviderInfo cpi =
8888                    (ProviderInfo)providers.get(i);
8889                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8890                        cpi.name, cpi.flags);
8891                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8892                    // This is a singleton provider, but a user besides the
8893                    // default user is asking to initialize a process it runs
8894                    // in...  well, no, it doesn't actually run in this process,
8895                    // it runs in the process of the default user.  Get rid of it.
8896                    providers.remove(i);
8897                    N--;
8898                    i--;
8899                    continue;
8900                }
8901
8902                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8903                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8904                if (cpr == null) {
8905                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8906                    mProviderMap.putProviderByClass(comp, cpr);
8907                }
8908                if (DEBUG_MU)
8909                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8910                app.pubProviders.put(cpi.name, cpr);
8911                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8912                    // Don't add this if it is a platform component that is marked
8913                    // to run in multiple processes, because this is actually
8914                    // part of the framework so doesn't make sense to track as a
8915                    // separate apk in the process.
8916                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8917                            mProcessStats);
8918                }
8919                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8920            }
8921        }
8922        return providers;
8923    }
8924
8925    /**
8926     * Check if {@link ProcessRecord} has a possible chance at accessing the
8927     * given {@link ProviderInfo}. Final permission checking is always done
8928     * in {@link ContentProvider}.
8929     */
8930    private final String checkContentProviderPermissionLocked(
8931            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8932        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8933        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8934        boolean checkedGrants = false;
8935        if (checkUser) {
8936            // Looking for cross-user grants before enforcing the typical cross-users permissions
8937            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8938            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8939                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8940                    return null;
8941                }
8942                checkedGrants = true;
8943            }
8944            userId = handleIncomingUser(callingPid, callingUid, userId,
8945                    false, ALLOW_NON_FULL,
8946                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8947            if (userId != tmpTargetUserId) {
8948                // When we actually went to determine the final targer user ID, this ended
8949                // up different than our initial check for the authority.  This is because
8950                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8951                // SELF.  So we need to re-check the grants again.
8952                checkedGrants = false;
8953            }
8954        }
8955        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8956                cpi.applicationInfo.uid, cpi.exported)
8957                == PackageManager.PERMISSION_GRANTED) {
8958            return null;
8959        }
8960        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8961                cpi.applicationInfo.uid, cpi.exported)
8962                == PackageManager.PERMISSION_GRANTED) {
8963            return null;
8964        }
8965
8966        PathPermission[] pps = cpi.pathPermissions;
8967        if (pps != null) {
8968            int i = pps.length;
8969            while (i > 0) {
8970                i--;
8971                PathPermission pp = pps[i];
8972                String pprperm = pp.getReadPermission();
8973                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8974                        cpi.applicationInfo.uid, cpi.exported)
8975                        == PackageManager.PERMISSION_GRANTED) {
8976                    return null;
8977                }
8978                String ppwperm = pp.getWritePermission();
8979                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8980                        cpi.applicationInfo.uid, cpi.exported)
8981                        == PackageManager.PERMISSION_GRANTED) {
8982                    return null;
8983                }
8984            }
8985        }
8986        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8987            return null;
8988        }
8989
8990        String msg;
8991        if (!cpi.exported) {
8992            msg = "Permission Denial: opening provider " + cpi.name
8993                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8994                    + ", uid=" + callingUid + ") that is not exported from uid "
8995                    + cpi.applicationInfo.uid;
8996        } else {
8997            msg = "Permission Denial: opening provider " + cpi.name
8998                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8999                    + ", uid=" + callingUid + ") requires "
9000                    + cpi.readPermission + " or " + cpi.writePermission;
9001        }
9002        Slog.w(TAG, msg);
9003        return msg;
9004    }
9005
9006    /**
9007     * Returns if the ContentProvider has granted a uri to callingUid
9008     */
9009    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9010        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9011        if (perms != null) {
9012            for (int i=perms.size()-1; i>=0; i--) {
9013                GrantUri grantUri = perms.keyAt(i);
9014                if (grantUri.sourceUserId == userId || !checkUser) {
9015                    if (matchesProvider(grantUri.uri, cpi)) {
9016                        return true;
9017                    }
9018                }
9019            }
9020        }
9021        return false;
9022    }
9023
9024    /**
9025     * Returns true if the uri authority is one of the authorities specified in the provider.
9026     */
9027    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9028        String uriAuth = uri.getAuthority();
9029        String cpiAuth = cpi.authority;
9030        if (cpiAuth.indexOf(';') == -1) {
9031            return cpiAuth.equals(uriAuth);
9032        }
9033        String[] cpiAuths = cpiAuth.split(";");
9034        int length = cpiAuths.length;
9035        for (int i = 0; i < length; i++) {
9036            if (cpiAuths[i].equals(uriAuth)) return true;
9037        }
9038        return false;
9039    }
9040
9041    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9042            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9043        if (r != null) {
9044            for (int i=0; i<r.conProviders.size(); i++) {
9045                ContentProviderConnection conn = r.conProviders.get(i);
9046                if (conn.provider == cpr) {
9047                    if (DEBUG_PROVIDER) Slog.v(TAG,
9048                            "Adding provider requested by "
9049                            + r.processName + " from process "
9050                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9051                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9052                    if (stable) {
9053                        conn.stableCount++;
9054                        conn.numStableIncs++;
9055                    } else {
9056                        conn.unstableCount++;
9057                        conn.numUnstableIncs++;
9058                    }
9059                    return conn;
9060                }
9061            }
9062            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9063            if (stable) {
9064                conn.stableCount = 1;
9065                conn.numStableIncs = 1;
9066            } else {
9067                conn.unstableCount = 1;
9068                conn.numUnstableIncs = 1;
9069            }
9070            cpr.connections.add(conn);
9071            r.conProviders.add(conn);
9072            return conn;
9073        }
9074        cpr.addExternalProcessHandleLocked(externalProcessToken);
9075        return null;
9076    }
9077
9078    boolean decProviderCountLocked(ContentProviderConnection conn,
9079            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9080        if (conn != null) {
9081            cpr = conn.provider;
9082            if (DEBUG_PROVIDER) Slog.v(TAG,
9083                    "Removing provider requested by "
9084                    + conn.client.processName + " from process "
9085                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9086                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9087            if (stable) {
9088                conn.stableCount--;
9089            } else {
9090                conn.unstableCount--;
9091            }
9092            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9093                cpr.connections.remove(conn);
9094                conn.client.conProviders.remove(conn);
9095                return true;
9096            }
9097            return false;
9098        }
9099        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9100        return false;
9101    }
9102
9103    private void checkTime(long startTime, String where) {
9104        long now = SystemClock.elapsedRealtime();
9105        if ((now-startTime) > 1000) {
9106            // If we are taking more than a second, log about it.
9107            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9108        }
9109    }
9110
9111    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9112            String name, IBinder token, boolean stable, int userId) {
9113        ContentProviderRecord cpr;
9114        ContentProviderConnection conn = null;
9115        ProviderInfo cpi = null;
9116
9117        synchronized(this) {
9118            long startTime = SystemClock.elapsedRealtime();
9119
9120            ProcessRecord r = null;
9121            if (caller != null) {
9122                r = getRecordForAppLocked(caller);
9123                if (r == null) {
9124                    throw new SecurityException(
9125                            "Unable to find app for caller " + caller
9126                          + " (pid=" + Binder.getCallingPid()
9127                          + ") when getting content provider " + name);
9128                }
9129            }
9130
9131            boolean checkCrossUser = true;
9132
9133            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9134
9135            // First check if this content provider has been published...
9136            cpr = mProviderMap.getProviderByName(name, userId);
9137            // If that didn't work, check if it exists for user 0 and then
9138            // verify that it's a singleton provider before using it.
9139            if (cpr == null && userId != UserHandle.USER_OWNER) {
9140                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9141                if (cpr != null) {
9142                    cpi = cpr.info;
9143                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9144                            cpi.name, cpi.flags)
9145                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9146                        userId = UserHandle.USER_OWNER;
9147                        checkCrossUser = false;
9148                    } else {
9149                        cpr = null;
9150                        cpi = null;
9151                    }
9152                }
9153            }
9154
9155            boolean providerRunning = cpr != null;
9156            if (providerRunning) {
9157                cpi = cpr.info;
9158                String msg;
9159                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9160                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9161                        != null) {
9162                    throw new SecurityException(msg);
9163                }
9164                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9165
9166                if (r != null && cpr.canRunHere(r)) {
9167                    // This provider has been published or is in the process
9168                    // of being published...  but it is also allowed to run
9169                    // in the caller's process, so don't make a connection
9170                    // and just let the caller instantiate its own instance.
9171                    ContentProviderHolder holder = cpr.newHolder(null);
9172                    // don't give caller the provider object, it needs
9173                    // to make its own.
9174                    holder.provider = null;
9175                    return holder;
9176                }
9177
9178                final long origId = Binder.clearCallingIdentity();
9179
9180                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9181
9182                // In this case the provider instance already exists, so we can
9183                // return it right away.
9184                conn = incProviderCountLocked(r, cpr, token, stable);
9185                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9186                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9187                        // If this is a perceptible app accessing the provider,
9188                        // make sure to count it as being accessed and thus
9189                        // back up on the LRU list.  This is good because
9190                        // content providers are often expensive to start.
9191                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9192                        updateLruProcessLocked(cpr.proc, false, null);
9193                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9194                    }
9195                }
9196
9197                if (cpr.proc != null) {
9198                    if (false) {
9199                        if (cpr.name.flattenToShortString().equals(
9200                                "com.android.providers.calendar/.CalendarProvider2")) {
9201                            Slog.v(TAG, "****************** KILLING "
9202                                + cpr.name.flattenToShortString());
9203                            Process.killProcess(cpr.proc.pid);
9204                        }
9205                    }
9206                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9207                    boolean success = updateOomAdjLocked(cpr.proc);
9208                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9209                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9210                    // NOTE: there is still a race here where a signal could be
9211                    // pending on the process even though we managed to update its
9212                    // adj level.  Not sure what to do about this, but at least
9213                    // the race is now smaller.
9214                    if (!success) {
9215                        // Uh oh...  it looks like the provider's process
9216                        // has been killed on us.  We need to wait for a new
9217                        // process to be started, and make sure its death
9218                        // doesn't kill our process.
9219                        Slog.i(TAG,
9220                                "Existing provider " + cpr.name.flattenToShortString()
9221                                + " is crashing; detaching " + r);
9222                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9223                        checkTime(startTime, "getContentProviderImpl: before appDied");
9224                        appDiedLocked(cpr.proc);
9225                        checkTime(startTime, "getContentProviderImpl: after appDied");
9226                        if (!lastRef) {
9227                            // This wasn't the last ref our process had on
9228                            // the provider...  we have now been killed, bail.
9229                            return null;
9230                        }
9231                        providerRunning = false;
9232                        conn = null;
9233                    }
9234                }
9235
9236                Binder.restoreCallingIdentity(origId);
9237            }
9238
9239            boolean singleton;
9240            if (!providerRunning) {
9241                try {
9242                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9243                    cpi = AppGlobals.getPackageManager().
9244                        resolveContentProvider(name,
9245                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9246                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9247                } catch (RemoteException ex) {
9248                }
9249                if (cpi == null) {
9250                    return null;
9251                }
9252                // If the provider is a singleton AND
9253                // (it's a call within the same user || the provider is a
9254                // privileged app)
9255                // Then allow connecting to the singleton provider
9256                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9257                        cpi.name, cpi.flags)
9258                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9259                if (singleton) {
9260                    userId = UserHandle.USER_OWNER;
9261                }
9262                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9263                checkTime(startTime, "getContentProviderImpl: got app info for user");
9264
9265                String msg;
9266                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9267                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9268                        != null) {
9269                    throw new SecurityException(msg);
9270                }
9271                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9272
9273                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9274                        && !cpi.processName.equals("system")) {
9275                    // If this content provider does not run in the system
9276                    // process, and the system is not yet ready to run other
9277                    // processes, then fail fast instead of hanging.
9278                    throw new IllegalArgumentException(
9279                            "Attempt to launch content provider before system ready");
9280                }
9281
9282                // Make sure that the user who owns this provider is started.  If not,
9283                // we don't want to allow it to run.
9284                if (mStartedUsers.get(userId) == null) {
9285                    Slog.w(TAG, "Unable to launch app "
9286                            + cpi.applicationInfo.packageName + "/"
9287                            + cpi.applicationInfo.uid + " for provider "
9288                            + name + ": user " + userId + " is stopped");
9289                    return null;
9290                }
9291
9292                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9293                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9294                cpr = mProviderMap.getProviderByClass(comp, userId);
9295                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9296                final boolean firstClass = cpr == null;
9297                if (firstClass) {
9298                    final long ident = Binder.clearCallingIdentity();
9299                    try {
9300                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9301                        ApplicationInfo ai =
9302                            AppGlobals.getPackageManager().
9303                                getApplicationInfo(
9304                                        cpi.applicationInfo.packageName,
9305                                        STOCK_PM_FLAGS, userId);
9306                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9307                        if (ai == null) {
9308                            Slog.w(TAG, "No package info for content provider "
9309                                    + cpi.name);
9310                            return null;
9311                        }
9312                        ai = getAppInfoForUser(ai, userId);
9313                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9314                    } catch (RemoteException ex) {
9315                        // pm is in same process, this will never happen.
9316                    } finally {
9317                        Binder.restoreCallingIdentity(ident);
9318                    }
9319                }
9320
9321                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9322
9323                if (r != null && cpr.canRunHere(r)) {
9324                    // If this is a multiprocess provider, then just return its
9325                    // info and allow the caller to instantiate it.  Only do
9326                    // this if the provider is the same user as the caller's
9327                    // process, or can run as root (so can be in any process).
9328                    return cpr.newHolder(null);
9329                }
9330
9331                if (DEBUG_PROVIDER) {
9332                    RuntimeException e = new RuntimeException("here");
9333                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9334                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9335                }
9336
9337                // This is single process, and our app is now connecting to it.
9338                // See if we are already in the process of launching this
9339                // provider.
9340                final int N = mLaunchingProviders.size();
9341                int i;
9342                for (i=0; i<N; i++) {
9343                    if (mLaunchingProviders.get(i) == cpr) {
9344                        break;
9345                    }
9346                }
9347
9348                // If the provider is not already being launched, then get it
9349                // started.
9350                if (i >= N) {
9351                    final long origId = Binder.clearCallingIdentity();
9352
9353                    try {
9354                        // Content provider is now in use, its package can't be stopped.
9355                        try {
9356                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9357                            AppGlobals.getPackageManager().setPackageStoppedState(
9358                                    cpr.appInfo.packageName, false, userId);
9359                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9360                        } catch (RemoteException e) {
9361                        } catch (IllegalArgumentException e) {
9362                            Slog.w(TAG, "Failed trying to unstop package "
9363                                    + cpr.appInfo.packageName + ": " + e);
9364                        }
9365
9366                        // Use existing process if already started
9367                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9368                        ProcessRecord proc = getProcessRecordLocked(
9369                                cpi.processName, cpr.appInfo.uid, false);
9370                        if (proc != null && proc.thread != null) {
9371                            if (DEBUG_PROVIDER) {
9372                                Slog.d(TAG, "Installing in existing process " + proc);
9373                            }
9374                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9375                            proc.pubProviders.put(cpi.name, cpr);
9376                            try {
9377                                proc.thread.scheduleInstallProvider(cpi);
9378                            } catch (RemoteException e) {
9379                            }
9380                        } else {
9381                            checkTime(startTime, "getContentProviderImpl: before start process");
9382                            proc = startProcessLocked(cpi.processName,
9383                                    cpr.appInfo, false, 0, "content provider",
9384                                    new ComponentName(cpi.applicationInfo.packageName,
9385                                            cpi.name), false, false, false);
9386                            checkTime(startTime, "getContentProviderImpl: after start process");
9387                            if (proc == null) {
9388                                Slog.w(TAG, "Unable to launch app "
9389                                        + cpi.applicationInfo.packageName + "/"
9390                                        + cpi.applicationInfo.uid + " for provider "
9391                                        + name + ": process is bad");
9392                                return null;
9393                            }
9394                        }
9395                        cpr.launchingApp = proc;
9396                        mLaunchingProviders.add(cpr);
9397                    } finally {
9398                        Binder.restoreCallingIdentity(origId);
9399                    }
9400                }
9401
9402                checkTime(startTime, "getContentProviderImpl: updating data structures");
9403
9404                // Make sure the provider is published (the same provider class
9405                // may be published under multiple names).
9406                if (firstClass) {
9407                    mProviderMap.putProviderByClass(comp, cpr);
9408                }
9409
9410                mProviderMap.putProviderByName(name, cpr);
9411                conn = incProviderCountLocked(r, cpr, token, stable);
9412                if (conn != null) {
9413                    conn.waiting = true;
9414                }
9415            }
9416            checkTime(startTime, "getContentProviderImpl: done!");
9417        }
9418
9419        // Wait for the provider to be published...
9420        synchronized (cpr) {
9421            while (cpr.provider == null) {
9422                if (cpr.launchingApp == null) {
9423                    Slog.w(TAG, "Unable to launch app "
9424                            + cpi.applicationInfo.packageName + "/"
9425                            + cpi.applicationInfo.uid + " for provider "
9426                            + name + ": launching app became null");
9427                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9428                            UserHandle.getUserId(cpi.applicationInfo.uid),
9429                            cpi.applicationInfo.packageName,
9430                            cpi.applicationInfo.uid, name);
9431                    return null;
9432                }
9433                try {
9434                    if (DEBUG_MU) {
9435                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9436                                + cpr.launchingApp);
9437                    }
9438                    if (conn != null) {
9439                        conn.waiting = true;
9440                    }
9441                    cpr.wait();
9442                } catch (InterruptedException ex) {
9443                } finally {
9444                    if (conn != null) {
9445                        conn.waiting = false;
9446                    }
9447                }
9448            }
9449        }
9450        return cpr != null ? cpr.newHolder(conn) : null;
9451    }
9452
9453    @Override
9454    public final ContentProviderHolder getContentProvider(
9455            IApplicationThread caller, String name, int userId, boolean stable) {
9456        enforceNotIsolatedCaller("getContentProvider");
9457        if (caller == null) {
9458            String msg = "null IApplicationThread when getting content provider "
9459                    + name;
9460            Slog.w(TAG, msg);
9461            throw new SecurityException(msg);
9462        }
9463        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9464        // with cross-user grant.
9465        return getContentProviderImpl(caller, name, null, stable, userId);
9466    }
9467
9468    public ContentProviderHolder getContentProviderExternal(
9469            String name, int userId, IBinder token) {
9470        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9471            "Do not have permission in call getContentProviderExternal()");
9472        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9473                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9474        return getContentProviderExternalUnchecked(name, token, userId);
9475    }
9476
9477    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9478            IBinder token, int userId) {
9479        return getContentProviderImpl(null, name, token, true, userId);
9480    }
9481
9482    /**
9483     * Drop a content provider from a ProcessRecord's bookkeeping
9484     */
9485    public void removeContentProvider(IBinder connection, boolean stable) {
9486        enforceNotIsolatedCaller("removeContentProvider");
9487        long ident = Binder.clearCallingIdentity();
9488        try {
9489            synchronized (this) {
9490                ContentProviderConnection conn;
9491                try {
9492                    conn = (ContentProviderConnection)connection;
9493                } catch (ClassCastException e) {
9494                    String msg ="removeContentProvider: " + connection
9495                            + " not a ContentProviderConnection";
9496                    Slog.w(TAG, msg);
9497                    throw new IllegalArgumentException(msg);
9498                }
9499                if (conn == null) {
9500                    throw new NullPointerException("connection is null");
9501                }
9502                if (decProviderCountLocked(conn, null, null, stable)) {
9503                    updateOomAdjLocked();
9504                }
9505            }
9506        } finally {
9507            Binder.restoreCallingIdentity(ident);
9508        }
9509    }
9510
9511    public void removeContentProviderExternal(String name, IBinder token) {
9512        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9513            "Do not have permission in call removeContentProviderExternal()");
9514        int userId = UserHandle.getCallingUserId();
9515        long ident = Binder.clearCallingIdentity();
9516        try {
9517            removeContentProviderExternalUnchecked(name, token, userId);
9518        } finally {
9519            Binder.restoreCallingIdentity(ident);
9520        }
9521    }
9522
9523    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9524        synchronized (this) {
9525            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9526            if(cpr == null) {
9527                //remove from mProvidersByClass
9528                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9529                return;
9530            }
9531
9532            //update content provider record entry info
9533            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9534            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9535            if (localCpr.hasExternalProcessHandles()) {
9536                if (localCpr.removeExternalProcessHandleLocked(token)) {
9537                    updateOomAdjLocked();
9538                } else {
9539                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9540                            + " with no external reference for token: "
9541                            + token + ".");
9542                }
9543            } else {
9544                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9545                        + " with no external references.");
9546            }
9547        }
9548    }
9549
9550    public final void publishContentProviders(IApplicationThread caller,
9551            List<ContentProviderHolder> providers) {
9552        if (providers == null) {
9553            return;
9554        }
9555
9556        enforceNotIsolatedCaller("publishContentProviders");
9557        synchronized (this) {
9558            final ProcessRecord r = getRecordForAppLocked(caller);
9559            if (DEBUG_MU)
9560                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9561            if (r == null) {
9562                throw new SecurityException(
9563                        "Unable to find app for caller " + caller
9564                      + " (pid=" + Binder.getCallingPid()
9565                      + ") when publishing content providers");
9566            }
9567
9568            final long origId = Binder.clearCallingIdentity();
9569
9570            final int N = providers.size();
9571            for (int i=0; i<N; i++) {
9572                ContentProviderHolder src = providers.get(i);
9573                if (src == null || src.info == null || src.provider == null) {
9574                    continue;
9575                }
9576                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9577                if (DEBUG_MU)
9578                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9579                if (dst != null) {
9580                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9581                    mProviderMap.putProviderByClass(comp, dst);
9582                    String names[] = dst.info.authority.split(";");
9583                    for (int j = 0; j < names.length; j++) {
9584                        mProviderMap.putProviderByName(names[j], dst);
9585                    }
9586
9587                    int NL = mLaunchingProviders.size();
9588                    int j;
9589                    for (j=0; j<NL; j++) {
9590                        if (mLaunchingProviders.get(j) == dst) {
9591                            mLaunchingProviders.remove(j);
9592                            j--;
9593                            NL--;
9594                        }
9595                    }
9596                    synchronized (dst) {
9597                        dst.provider = src.provider;
9598                        dst.proc = r;
9599                        dst.notifyAll();
9600                    }
9601                    updateOomAdjLocked(r);
9602                }
9603            }
9604
9605            Binder.restoreCallingIdentity(origId);
9606        }
9607    }
9608
9609    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9610        ContentProviderConnection conn;
9611        try {
9612            conn = (ContentProviderConnection)connection;
9613        } catch (ClassCastException e) {
9614            String msg ="refContentProvider: " + connection
9615                    + " not a ContentProviderConnection";
9616            Slog.w(TAG, msg);
9617            throw new IllegalArgumentException(msg);
9618        }
9619        if (conn == null) {
9620            throw new NullPointerException("connection is null");
9621        }
9622
9623        synchronized (this) {
9624            if (stable > 0) {
9625                conn.numStableIncs += stable;
9626            }
9627            stable = conn.stableCount + stable;
9628            if (stable < 0) {
9629                throw new IllegalStateException("stableCount < 0: " + stable);
9630            }
9631
9632            if (unstable > 0) {
9633                conn.numUnstableIncs += unstable;
9634            }
9635            unstable = conn.unstableCount + unstable;
9636            if (unstable < 0) {
9637                throw new IllegalStateException("unstableCount < 0: " + unstable);
9638            }
9639
9640            if ((stable+unstable) <= 0) {
9641                throw new IllegalStateException("ref counts can't go to zero here: stable="
9642                        + stable + " unstable=" + unstable);
9643            }
9644            conn.stableCount = stable;
9645            conn.unstableCount = unstable;
9646            return !conn.dead;
9647        }
9648    }
9649
9650    public void unstableProviderDied(IBinder connection) {
9651        ContentProviderConnection conn;
9652        try {
9653            conn = (ContentProviderConnection)connection;
9654        } catch (ClassCastException e) {
9655            String msg ="refContentProvider: " + connection
9656                    + " not a ContentProviderConnection";
9657            Slog.w(TAG, msg);
9658            throw new IllegalArgumentException(msg);
9659        }
9660        if (conn == null) {
9661            throw new NullPointerException("connection is null");
9662        }
9663
9664        // Safely retrieve the content provider associated with the connection.
9665        IContentProvider provider;
9666        synchronized (this) {
9667            provider = conn.provider.provider;
9668        }
9669
9670        if (provider == null) {
9671            // Um, yeah, we're way ahead of you.
9672            return;
9673        }
9674
9675        // Make sure the caller is being honest with us.
9676        if (provider.asBinder().pingBinder()) {
9677            // Er, no, still looks good to us.
9678            synchronized (this) {
9679                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9680                        + " says " + conn + " died, but we don't agree");
9681                return;
9682            }
9683        }
9684
9685        // Well look at that!  It's dead!
9686        synchronized (this) {
9687            if (conn.provider.provider != provider) {
9688                // But something changed...  good enough.
9689                return;
9690            }
9691
9692            ProcessRecord proc = conn.provider.proc;
9693            if (proc == null || proc.thread == null) {
9694                // Seems like the process is already cleaned up.
9695                return;
9696            }
9697
9698            // As far as we're concerned, this is just like receiving a
9699            // death notification...  just a bit prematurely.
9700            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9701                    + ") early provider death");
9702            final long ident = Binder.clearCallingIdentity();
9703            try {
9704                appDiedLocked(proc);
9705            } finally {
9706                Binder.restoreCallingIdentity(ident);
9707            }
9708        }
9709    }
9710
9711    @Override
9712    public void appNotRespondingViaProvider(IBinder connection) {
9713        enforceCallingPermission(
9714                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9715
9716        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9717        if (conn == null) {
9718            Slog.w(TAG, "ContentProviderConnection is null");
9719            return;
9720        }
9721
9722        final ProcessRecord host = conn.provider.proc;
9723        if (host == null) {
9724            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9725            return;
9726        }
9727
9728        final long token = Binder.clearCallingIdentity();
9729        try {
9730            appNotResponding(host, null, null, false, "ContentProvider not responding");
9731        } finally {
9732            Binder.restoreCallingIdentity(token);
9733        }
9734    }
9735
9736    public final void installSystemProviders() {
9737        List<ProviderInfo> providers;
9738        synchronized (this) {
9739            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9740            providers = generateApplicationProvidersLocked(app);
9741            if (providers != null) {
9742                for (int i=providers.size()-1; i>=0; i--) {
9743                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9744                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9745                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9746                                + ": not system .apk");
9747                        providers.remove(i);
9748                    }
9749                }
9750            }
9751        }
9752        if (providers != null) {
9753            mSystemThread.installSystemProviders(providers);
9754        }
9755
9756        mCoreSettingsObserver = new CoreSettingsObserver(this);
9757
9758        //mUsageStatsService.monitorPackages();
9759    }
9760
9761    /**
9762     * Allows apps to retrieve the MIME type of a URI.
9763     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9764     * users, then it does not need permission to access the ContentProvider.
9765     * Either, it needs cross-user uri grants.
9766     *
9767     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9768     *
9769     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9770     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9771     */
9772    public String getProviderMimeType(Uri uri, int userId) {
9773        enforceNotIsolatedCaller("getProviderMimeType");
9774        final String name = uri.getAuthority();
9775        int callingUid = Binder.getCallingUid();
9776        int callingPid = Binder.getCallingPid();
9777        long ident = 0;
9778        boolean clearedIdentity = false;
9779        userId = unsafeConvertIncomingUser(userId);
9780        if (canClearIdentity(callingPid, callingUid, userId)) {
9781            clearedIdentity = true;
9782            ident = Binder.clearCallingIdentity();
9783        }
9784        ContentProviderHolder holder = null;
9785        try {
9786            holder = getContentProviderExternalUnchecked(name, null, userId);
9787            if (holder != null) {
9788                return holder.provider.getType(uri);
9789            }
9790        } catch (RemoteException e) {
9791            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9792            return null;
9793        } finally {
9794            // We need to clear the identity to call removeContentProviderExternalUnchecked
9795            if (!clearedIdentity) {
9796                ident = Binder.clearCallingIdentity();
9797            }
9798            try {
9799                if (holder != null) {
9800                    removeContentProviderExternalUnchecked(name, null, userId);
9801                }
9802            } finally {
9803                Binder.restoreCallingIdentity(ident);
9804            }
9805        }
9806
9807        return null;
9808    }
9809
9810    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9811        if (UserHandle.getUserId(callingUid) == userId) {
9812            return true;
9813        }
9814        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9815                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9816                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9817                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9818                return true;
9819        }
9820        return false;
9821    }
9822
9823    // =========================================================
9824    // GLOBAL MANAGEMENT
9825    // =========================================================
9826
9827    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9828            boolean isolated, int isolatedUid) {
9829        String proc = customProcess != null ? customProcess : info.processName;
9830        BatteryStatsImpl.Uid.Proc ps = null;
9831        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9832        int uid = info.uid;
9833        if (isolated) {
9834            if (isolatedUid == 0) {
9835                int userId = UserHandle.getUserId(uid);
9836                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9837                while (true) {
9838                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9839                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9840                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9841                    }
9842                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9843                    mNextIsolatedProcessUid++;
9844                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9845                        // No process for this uid, use it.
9846                        break;
9847                    }
9848                    stepsLeft--;
9849                    if (stepsLeft <= 0) {
9850                        return null;
9851                    }
9852                }
9853            } else {
9854                // Special case for startIsolatedProcess (internal only), where
9855                // the uid of the isolated process is specified by the caller.
9856                uid = isolatedUid;
9857            }
9858        }
9859        return new ProcessRecord(stats, info, proc, uid);
9860    }
9861
9862    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9863            String abiOverride) {
9864        ProcessRecord app;
9865        if (!isolated) {
9866            app = getProcessRecordLocked(info.processName, info.uid, true);
9867        } else {
9868            app = null;
9869        }
9870
9871        if (app == null) {
9872            app = newProcessRecordLocked(info, null, isolated, 0);
9873            mProcessNames.put(info.processName, app.uid, app);
9874            if (isolated) {
9875                mIsolatedProcesses.put(app.uid, app);
9876            }
9877            updateLruProcessLocked(app, false, null);
9878            updateOomAdjLocked();
9879        }
9880
9881        // This package really, really can not be stopped.
9882        try {
9883            AppGlobals.getPackageManager().setPackageStoppedState(
9884                    info.packageName, false, UserHandle.getUserId(app.uid));
9885        } catch (RemoteException e) {
9886        } catch (IllegalArgumentException e) {
9887            Slog.w(TAG, "Failed trying to unstop package "
9888                    + info.packageName + ": " + e);
9889        }
9890
9891        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9892                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9893            app.persistent = true;
9894            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9895        }
9896        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9897            mPersistentStartingProcesses.add(app);
9898            startProcessLocked(app, "added application", app.processName, abiOverride,
9899                    null /* entryPoint */, null /* entryPointArgs */);
9900        }
9901
9902        return app;
9903    }
9904
9905    public void unhandledBack() {
9906        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9907                "unhandledBack()");
9908
9909        synchronized(this) {
9910            final long origId = Binder.clearCallingIdentity();
9911            try {
9912                getFocusedStack().unhandledBackLocked();
9913            } finally {
9914                Binder.restoreCallingIdentity(origId);
9915            }
9916        }
9917    }
9918
9919    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9920        enforceNotIsolatedCaller("openContentUri");
9921        final int userId = UserHandle.getCallingUserId();
9922        String name = uri.getAuthority();
9923        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9924        ParcelFileDescriptor pfd = null;
9925        if (cph != null) {
9926            // We record the binder invoker's uid in thread-local storage before
9927            // going to the content provider to open the file.  Later, in the code
9928            // that handles all permissions checks, we look for this uid and use
9929            // that rather than the Activity Manager's own uid.  The effect is that
9930            // we do the check against the caller's permissions even though it looks
9931            // to the content provider like the Activity Manager itself is making
9932            // the request.
9933            Binder token = new Binder();
9934            sCallerIdentity.set(new Identity(
9935                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9936            try {
9937                pfd = cph.provider.openFile(null, uri, "r", null, token);
9938            } catch (FileNotFoundException e) {
9939                // do nothing; pfd will be returned null
9940            } finally {
9941                // Ensure that whatever happens, we clean up the identity state
9942                sCallerIdentity.remove();
9943            }
9944
9945            // We've got the fd now, so we're done with the provider.
9946            removeContentProviderExternalUnchecked(name, null, userId);
9947        } else {
9948            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9949        }
9950        return pfd;
9951    }
9952
9953    // Actually is sleeping or shutting down or whatever else in the future
9954    // is an inactive state.
9955    public boolean isSleepingOrShuttingDown() {
9956        return isSleeping() || mShuttingDown;
9957    }
9958
9959    public boolean isSleeping() {
9960        return mSleeping;
9961    }
9962
9963    void onWakefulnessChanged(int wakefulness) {
9964        synchronized(this) {
9965            mWakefulness = wakefulness;
9966            updateSleepIfNeededLocked();
9967        }
9968    }
9969
9970    void finishRunningVoiceLocked() {
9971        if (mRunningVoice) {
9972            mRunningVoice = false;
9973            updateSleepIfNeededLocked();
9974        }
9975    }
9976
9977    void updateSleepIfNeededLocked() {
9978        if (mSleeping && !shouldSleepLocked()) {
9979            mSleeping = false;
9980            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9981        } else if (!mSleeping && shouldSleepLocked()) {
9982            mSleeping = true;
9983            mStackSupervisor.goingToSleepLocked();
9984
9985            // Initialize the wake times of all processes.
9986            checkExcessivePowerUsageLocked(false);
9987            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9988            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9989            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9990        }
9991    }
9992
9993    private boolean shouldSleepLocked() {
9994        // Resume applications while running a voice interactor.
9995        if (mRunningVoice) {
9996            return false;
9997        }
9998
9999        switch (mWakefulness) {
10000            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10001            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10002                // If we're interactive but applications are already paused then defer
10003                // resuming them until the lock screen is hidden.
10004                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10005            case PowerManagerInternal.WAKEFULNESS_DOZING:
10006                // If we're dozing then pause applications whenever the lock screen is shown.
10007                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10008            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10009            default:
10010                // If we're asleep then pause applications unconditionally.
10011                return true;
10012        }
10013    }
10014
10015    /** Pokes the task persister. */
10016    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10017        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10018            // Never persist the home stack.
10019            return;
10020        }
10021        mTaskPersister.wakeup(task, flush);
10022    }
10023
10024    /** Notifies all listeners when the task stack has changed. */
10025    void notifyTaskStackChangedLocked() {
10026        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10027        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10028        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10029    }
10030
10031    @Override
10032    public boolean shutdown(int timeout) {
10033        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10034                != PackageManager.PERMISSION_GRANTED) {
10035            throw new SecurityException("Requires permission "
10036                    + android.Manifest.permission.SHUTDOWN);
10037        }
10038
10039        boolean timedout = false;
10040
10041        synchronized(this) {
10042            mShuttingDown = true;
10043            updateEventDispatchingLocked();
10044            timedout = mStackSupervisor.shutdownLocked(timeout);
10045        }
10046
10047        mAppOpsService.shutdown();
10048        if (mUsageStatsService != null) {
10049            mUsageStatsService.prepareShutdown();
10050        }
10051        mBatteryStatsService.shutdown();
10052        synchronized (this) {
10053            mProcessStats.shutdownLocked();
10054            notifyTaskPersisterLocked(null, true);
10055        }
10056
10057        return timedout;
10058    }
10059
10060    public final void activitySlept(IBinder token) {
10061        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10062
10063        final long origId = Binder.clearCallingIdentity();
10064
10065        synchronized (this) {
10066            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10067            if (r != null) {
10068                mStackSupervisor.activitySleptLocked(r);
10069            }
10070        }
10071
10072        Binder.restoreCallingIdentity(origId);
10073    }
10074
10075    private String lockScreenShownToString() {
10076        switch (mLockScreenShown) {
10077            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10078            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10079            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10080            default: return "Unknown=" + mLockScreenShown;
10081        }
10082    }
10083
10084    void logLockScreen(String msg) {
10085        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10086                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10087                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10088                + " mSleeping=" + mSleeping);
10089    }
10090
10091    void startRunningVoiceLocked() {
10092        if (!mRunningVoice) {
10093            mRunningVoice = true;
10094            updateSleepIfNeededLocked();
10095        }
10096    }
10097
10098    private void updateEventDispatchingLocked() {
10099        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10100    }
10101
10102    public void setLockScreenShown(boolean shown) {
10103        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10104                != PackageManager.PERMISSION_GRANTED) {
10105            throw new SecurityException("Requires permission "
10106                    + android.Manifest.permission.DEVICE_POWER);
10107        }
10108
10109        synchronized(this) {
10110            long ident = Binder.clearCallingIdentity();
10111            try {
10112                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10113                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10114                updateSleepIfNeededLocked();
10115            } finally {
10116                Binder.restoreCallingIdentity(ident);
10117            }
10118        }
10119    }
10120
10121    @Override
10122    public void stopAppSwitches() {
10123        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10124                != PackageManager.PERMISSION_GRANTED) {
10125            throw new SecurityException("Requires permission "
10126                    + android.Manifest.permission.STOP_APP_SWITCHES);
10127        }
10128
10129        synchronized(this) {
10130            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10131                    + APP_SWITCH_DELAY_TIME;
10132            mDidAppSwitch = false;
10133            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10134            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10135            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10136        }
10137    }
10138
10139    public void resumeAppSwitches() {
10140        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10141                != PackageManager.PERMISSION_GRANTED) {
10142            throw new SecurityException("Requires permission "
10143                    + android.Manifest.permission.STOP_APP_SWITCHES);
10144        }
10145
10146        synchronized(this) {
10147            // Note that we don't execute any pending app switches... we will
10148            // let those wait until either the timeout, or the next start
10149            // activity request.
10150            mAppSwitchesAllowedTime = 0;
10151        }
10152    }
10153
10154    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10155            int callingPid, int callingUid, String name) {
10156        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10157            return true;
10158        }
10159
10160        int perm = checkComponentPermission(
10161                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10162                sourceUid, -1, true);
10163        if (perm == PackageManager.PERMISSION_GRANTED) {
10164            return true;
10165        }
10166
10167        // If the actual IPC caller is different from the logical source, then
10168        // also see if they are allowed to control app switches.
10169        if (callingUid != -1 && callingUid != sourceUid) {
10170            perm = checkComponentPermission(
10171                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10172                    callingUid, -1, true);
10173            if (perm == PackageManager.PERMISSION_GRANTED) {
10174                return true;
10175            }
10176        }
10177
10178        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10179        return false;
10180    }
10181
10182    public void setDebugApp(String packageName, boolean waitForDebugger,
10183            boolean persistent) {
10184        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10185                "setDebugApp()");
10186
10187        long ident = Binder.clearCallingIdentity();
10188        try {
10189            // Note that this is not really thread safe if there are multiple
10190            // callers into it at the same time, but that's not a situation we
10191            // care about.
10192            if (persistent) {
10193                final ContentResolver resolver = mContext.getContentResolver();
10194                Settings.Global.putString(
10195                    resolver, Settings.Global.DEBUG_APP,
10196                    packageName);
10197                Settings.Global.putInt(
10198                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10199                    waitForDebugger ? 1 : 0);
10200            }
10201
10202            synchronized (this) {
10203                if (!persistent) {
10204                    mOrigDebugApp = mDebugApp;
10205                    mOrigWaitForDebugger = mWaitForDebugger;
10206                }
10207                mDebugApp = packageName;
10208                mWaitForDebugger = waitForDebugger;
10209                mDebugTransient = !persistent;
10210                if (packageName != null) {
10211                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10212                            false, UserHandle.USER_ALL, "set debug app");
10213                }
10214            }
10215        } finally {
10216            Binder.restoreCallingIdentity(ident);
10217        }
10218    }
10219
10220    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10221        synchronized (this) {
10222            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10223            if (!isDebuggable) {
10224                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10225                    throw new SecurityException("Process not debuggable: " + app.packageName);
10226                }
10227            }
10228
10229            mOpenGlTraceApp = processName;
10230        }
10231    }
10232
10233    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10234        synchronized (this) {
10235            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10236            if (!isDebuggable) {
10237                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10238                    throw new SecurityException("Process not debuggable: " + app.packageName);
10239                }
10240            }
10241            mProfileApp = processName;
10242            mProfileFile = profilerInfo.profileFile;
10243            if (mProfileFd != null) {
10244                try {
10245                    mProfileFd.close();
10246                } catch (IOException e) {
10247                }
10248                mProfileFd = null;
10249            }
10250            mProfileFd = profilerInfo.profileFd;
10251            mSamplingInterval = profilerInfo.samplingInterval;
10252            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10253            mProfileType = 0;
10254        }
10255    }
10256
10257    @Override
10258    public void setAlwaysFinish(boolean enabled) {
10259        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10260                "setAlwaysFinish()");
10261
10262        Settings.Global.putInt(
10263                mContext.getContentResolver(),
10264                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10265
10266        synchronized (this) {
10267            mAlwaysFinishActivities = enabled;
10268        }
10269    }
10270
10271    @Override
10272    public void setActivityController(IActivityController controller) {
10273        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10274                "setActivityController()");
10275        synchronized (this) {
10276            mController = controller;
10277            Watchdog.getInstance().setActivityController(controller);
10278        }
10279    }
10280
10281    @Override
10282    public void setUserIsMonkey(boolean userIsMonkey) {
10283        synchronized (this) {
10284            synchronized (mPidsSelfLocked) {
10285                final int callingPid = Binder.getCallingPid();
10286                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10287                if (precessRecord == null) {
10288                    throw new SecurityException("Unknown process: " + callingPid);
10289                }
10290                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10291                    throw new SecurityException("Only an instrumentation process "
10292                            + "with a UiAutomation can call setUserIsMonkey");
10293                }
10294            }
10295            mUserIsMonkey = userIsMonkey;
10296        }
10297    }
10298
10299    @Override
10300    public boolean isUserAMonkey() {
10301        synchronized (this) {
10302            // If there is a controller also implies the user is a monkey.
10303            return (mUserIsMonkey || mController != null);
10304        }
10305    }
10306
10307    public void requestBugReport() {
10308        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10309        SystemProperties.set("ctl.start", "bugreport");
10310    }
10311
10312    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10313        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10314    }
10315
10316    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10317        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10318            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10319        }
10320        return KEY_DISPATCHING_TIMEOUT;
10321    }
10322
10323    @Override
10324    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10325        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10326                != PackageManager.PERMISSION_GRANTED) {
10327            throw new SecurityException("Requires permission "
10328                    + android.Manifest.permission.FILTER_EVENTS);
10329        }
10330        ProcessRecord proc;
10331        long timeout;
10332        synchronized (this) {
10333            synchronized (mPidsSelfLocked) {
10334                proc = mPidsSelfLocked.get(pid);
10335            }
10336            timeout = getInputDispatchingTimeoutLocked(proc);
10337        }
10338
10339        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10340            return -1;
10341        }
10342
10343        return timeout;
10344    }
10345
10346    /**
10347     * Handle input dispatching timeouts.
10348     * Returns whether input dispatching should be aborted or not.
10349     */
10350    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10351            final ActivityRecord activity, final ActivityRecord parent,
10352            final boolean aboveSystem, String reason) {
10353        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10354                != PackageManager.PERMISSION_GRANTED) {
10355            throw new SecurityException("Requires permission "
10356                    + android.Manifest.permission.FILTER_EVENTS);
10357        }
10358
10359        final String annotation;
10360        if (reason == null) {
10361            annotation = "Input dispatching timed out";
10362        } else {
10363            annotation = "Input dispatching timed out (" + reason + ")";
10364        }
10365
10366        if (proc != null) {
10367            synchronized (this) {
10368                if (proc.debugging) {
10369                    return false;
10370                }
10371
10372                if (mDidDexOpt) {
10373                    // Give more time since we were dexopting.
10374                    mDidDexOpt = false;
10375                    return false;
10376                }
10377
10378                if (proc.instrumentationClass != null) {
10379                    Bundle info = new Bundle();
10380                    info.putString("shortMsg", "keyDispatchingTimedOut");
10381                    info.putString("longMsg", annotation);
10382                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10383                    return true;
10384                }
10385            }
10386            mHandler.post(new Runnable() {
10387                @Override
10388                public void run() {
10389                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10390                }
10391            });
10392        }
10393
10394        return true;
10395    }
10396
10397    public Bundle getAssistContextExtras(int requestType) {
10398        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10399                UserHandle.getCallingUserId());
10400        if (pae == null) {
10401            return null;
10402        }
10403        synchronized (pae) {
10404            while (!pae.haveResult) {
10405                try {
10406                    pae.wait();
10407                } catch (InterruptedException e) {
10408                }
10409            }
10410            if (pae.result != null) {
10411                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10412            }
10413        }
10414        synchronized (this) {
10415            mPendingAssistExtras.remove(pae);
10416            mHandler.removeCallbacks(pae);
10417        }
10418        return pae.extras;
10419    }
10420
10421    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10422            int userHandle) {
10423        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10424                "getAssistContextExtras()");
10425        PendingAssistExtras pae;
10426        Bundle extras = new Bundle();
10427        synchronized (this) {
10428            ActivityRecord activity = getFocusedStack().mResumedActivity;
10429            if (activity == null) {
10430                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10431                return null;
10432            }
10433            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10434            if (activity.app == null || activity.app.thread == null) {
10435                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10436                return null;
10437            }
10438            if (activity.app.pid == Binder.getCallingPid()) {
10439                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10440                return null;
10441            }
10442            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10443            try {
10444                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10445                        requestType);
10446                mPendingAssistExtras.add(pae);
10447                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10448            } catch (RemoteException e) {
10449                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10450                return null;
10451            }
10452            return pae;
10453        }
10454    }
10455
10456    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10457        PendingAssistExtras pae = (PendingAssistExtras)token;
10458        synchronized (pae) {
10459            pae.result = extras;
10460            pae.haveResult = true;
10461            pae.notifyAll();
10462            if (pae.intent == null) {
10463                // Caller is just waiting for the result.
10464                return;
10465            }
10466        }
10467
10468        // We are now ready to launch the assist activity.
10469        synchronized (this) {
10470            boolean exists = mPendingAssistExtras.remove(pae);
10471            mHandler.removeCallbacks(pae);
10472            if (!exists) {
10473                // Timed out.
10474                return;
10475            }
10476        }
10477        pae.intent.replaceExtras(extras);
10478        if (pae.hint != null) {
10479            pae.intent.putExtra(pae.hint, true);
10480        }
10481        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10482                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10483                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10484        closeSystemDialogs("assist");
10485        try {
10486            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10487        } catch (ActivityNotFoundException e) {
10488            Slog.w(TAG, "No activity to handle assist action.", e);
10489        }
10490    }
10491
10492    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10493        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10494    }
10495
10496    public void registerProcessObserver(IProcessObserver observer) {
10497        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10498                "registerProcessObserver()");
10499        synchronized (this) {
10500            mProcessObservers.register(observer);
10501        }
10502    }
10503
10504    @Override
10505    public void unregisterProcessObserver(IProcessObserver observer) {
10506        synchronized (this) {
10507            mProcessObservers.unregister(observer);
10508        }
10509    }
10510
10511    @Override
10512    public boolean convertFromTranslucent(IBinder token) {
10513        final long origId = Binder.clearCallingIdentity();
10514        try {
10515            synchronized (this) {
10516                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10517                if (r == null) {
10518                    return false;
10519                }
10520                final boolean translucentChanged = r.changeWindowTranslucency(true);
10521                if (translucentChanged) {
10522                    r.task.stack.releaseBackgroundResources();
10523                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10524                }
10525                mWindowManager.setAppFullscreen(token, true);
10526                return translucentChanged;
10527            }
10528        } finally {
10529            Binder.restoreCallingIdentity(origId);
10530        }
10531    }
10532
10533    @Override
10534    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10535        final long origId = Binder.clearCallingIdentity();
10536        try {
10537            synchronized (this) {
10538                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10539                if (r == null) {
10540                    return false;
10541                }
10542                int index = r.task.mActivities.lastIndexOf(r);
10543                if (index > 0) {
10544                    ActivityRecord under = r.task.mActivities.get(index - 1);
10545                    under.returningOptions = options;
10546                }
10547                final boolean translucentChanged = r.changeWindowTranslucency(false);
10548                if (translucentChanged) {
10549                    r.task.stack.convertToTranslucent(r);
10550                }
10551                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10552                mWindowManager.setAppFullscreen(token, false);
10553                return translucentChanged;
10554            }
10555        } finally {
10556            Binder.restoreCallingIdentity(origId);
10557        }
10558    }
10559
10560    @Override
10561    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10562        final long origId = Binder.clearCallingIdentity();
10563        try {
10564            synchronized (this) {
10565                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10566                if (r != null) {
10567                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10568                }
10569            }
10570            return false;
10571        } finally {
10572            Binder.restoreCallingIdentity(origId);
10573        }
10574    }
10575
10576    @Override
10577    public boolean isBackgroundVisibleBehind(IBinder token) {
10578        final long origId = Binder.clearCallingIdentity();
10579        try {
10580            synchronized (this) {
10581                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10582                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10583                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10584                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10585                return visible;
10586            }
10587        } finally {
10588            Binder.restoreCallingIdentity(origId);
10589        }
10590    }
10591
10592    @Override
10593    public ActivityOptions getActivityOptions(IBinder token) {
10594        final long origId = Binder.clearCallingIdentity();
10595        try {
10596            synchronized (this) {
10597                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10598                if (r != null) {
10599                    final ActivityOptions activityOptions = r.pendingOptions;
10600                    r.pendingOptions = null;
10601                    return activityOptions;
10602                }
10603                return null;
10604            }
10605        } finally {
10606            Binder.restoreCallingIdentity(origId);
10607        }
10608    }
10609
10610    @Override
10611    public void setImmersive(IBinder token, boolean immersive) {
10612        synchronized(this) {
10613            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10614            if (r == null) {
10615                throw new IllegalArgumentException();
10616            }
10617            r.immersive = immersive;
10618
10619            // update associated state if we're frontmost
10620            if (r == mFocusedActivity) {
10621                if (DEBUG_IMMERSIVE) {
10622                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10623                }
10624                applyUpdateLockStateLocked(r);
10625            }
10626        }
10627    }
10628
10629    @Override
10630    public boolean isImmersive(IBinder token) {
10631        synchronized (this) {
10632            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10633            if (r == null) {
10634                throw new IllegalArgumentException();
10635            }
10636            return r.immersive;
10637        }
10638    }
10639
10640    public boolean isTopActivityImmersive() {
10641        enforceNotIsolatedCaller("startActivity");
10642        synchronized (this) {
10643            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10644            return (r != null) ? r.immersive : false;
10645        }
10646    }
10647
10648    @Override
10649    public boolean isTopOfTask(IBinder token) {
10650        synchronized (this) {
10651            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10652            if (r == null) {
10653                throw new IllegalArgumentException();
10654            }
10655            return r.task.getTopActivity() == r;
10656        }
10657    }
10658
10659    public final void enterSafeMode() {
10660        synchronized(this) {
10661            // It only makes sense to do this before the system is ready
10662            // and started launching other packages.
10663            if (!mSystemReady) {
10664                try {
10665                    AppGlobals.getPackageManager().enterSafeMode();
10666                } catch (RemoteException e) {
10667                }
10668            }
10669
10670            mSafeMode = true;
10671        }
10672    }
10673
10674    public final void showSafeModeOverlay() {
10675        View v = LayoutInflater.from(mContext).inflate(
10676                com.android.internal.R.layout.safe_mode, null);
10677        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10678        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10679        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10680        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10681        lp.gravity = Gravity.BOTTOM | Gravity.START;
10682        lp.format = v.getBackground().getOpacity();
10683        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10684                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10685        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10686        ((WindowManager)mContext.getSystemService(
10687                Context.WINDOW_SERVICE)).addView(v, lp);
10688    }
10689
10690    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10691        if (!(sender instanceof PendingIntentRecord)) {
10692            return;
10693        }
10694        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10695        synchronized (stats) {
10696            if (mBatteryStatsService.isOnBattery()) {
10697                mBatteryStatsService.enforceCallingPermission();
10698                PendingIntentRecord rec = (PendingIntentRecord)sender;
10699                int MY_UID = Binder.getCallingUid();
10700                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10701                BatteryStatsImpl.Uid.Pkg pkg =
10702                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10703                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10704                pkg.incWakeupsLocked();
10705            }
10706        }
10707    }
10708
10709    public boolean killPids(int[] pids, String pReason, boolean secure) {
10710        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10711            throw new SecurityException("killPids only available to the system");
10712        }
10713        String reason = (pReason == null) ? "Unknown" : pReason;
10714        // XXX Note: don't acquire main activity lock here, because the window
10715        // manager calls in with its locks held.
10716
10717        boolean killed = false;
10718        synchronized (mPidsSelfLocked) {
10719            int[] types = new int[pids.length];
10720            int worstType = 0;
10721            for (int i=0; i<pids.length; i++) {
10722                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10723                if (proc != null) {
10724                    int type = proc.setAdj;
10725                    types[i] = type;
10726                    if (type > worstType) {
10727                        worstType = type;
10728                    }
10729                }
10730            }
10731
10732            // If the worst oom_adj is somewhere in the cached proc LRU range,
10733            // then constrain it so we will kill all cached procs.
10734            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10735                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10736                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10737            }
10738
10739            // If this is not a secure call, don't let it kill processes that
10740            // are important.
10741            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10742                worstType = ProcessList.SERVICE_ADJ;
10743            }
10744
10745            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10746            for (int i=0; i<pids.length; i++) {
10747                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10748                if (proc == null) {
10749                    continue;
10750                }
10751                int adj = proc.setAdj;
10752                if (adj >= worstType && !proc.killedByAm) {
10753                    proc.kill(reason, true);
10754                    killed = true;
10755                }
10756            }
10757        }
10758        return killed;
10759    }
10760
10761    @Override
10762    public void killUid(int uid, String reason) {
10763        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10764            throw new SecurityException("killUid only available to the system");
10765        }
10766        synchronized (this) {
10767            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10768                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10769                    reason != null ? reason : "kill uid");
10770        }
10771    }
10772
10773    @Override
10774    public boolean killProcessesBelowForeground(String reason) {
10775        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10776            throw new SecurityException("killProcessesBelowForeground() only available to system");
10777        }
10778
10779        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10780    }
10781
10782    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10783        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10784            throw new SecurityException("killProcessesBelowAdj() only available to system");
10785        }
10786
10787        boolean killed = false;
10788        synchronized (mPidsSelfLocked) {
10789            final int size = mPidsSelfLocked.size();
10790            for (int i = 0; i < size; i++) {
10791                final int pid = mPidsSelfLocked.keyAt(i);
10792                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10793                if (proc == null) continue;
10794
10795                final int adj = proc.setAdj;
10796                if (adj > belowAdj && !proc.killedByAm) {
10797                    proc.kill(reason, true);
10798                    killed = true;
10799                }
10800            }
10801        }
10802        return killed;
10803    }
10804
10805    @Override
10806    public void hang(final IBinder who, boolean allowRestart) {
10807        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10808                != PackageManager.PERMISSION_GRANTED) {
10809            throw new SecurityException("Requires permission "
10810                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10811        }
10812
10813        final IBinder.DeathRecipient death = new DeathRecipient() {
10814            @Override
10815            public void binderDied() {
10816                synchronized (this) {
10817                    notifyAll();
10818                }
10819            }
10820        };
10821
10822        try {
10823            who.linkToDeath(death, 0);
10824        } catch (RemoteException e) {
10825            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10826            return;
10827        }
10828
10829        synchronized (this) {
10830            Watchdog.getInstance().setAllowRestart(allowRestart);
10831            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10832            synchronized (death) {
10833                while (who.isBinderAlive()) {
10834                    try {
10835                        death.wait();
10836                    } catch (InterruptedException e) {
10837                    }
10838                }
10839            }
10840            Watchdog.getInstance().setAllowRestart(true);
10841        }
10842    }
10843
10844    @Override
10845    public void restart() {
10846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10847                != PackageManager.PERMISSION_GRANTED) {
10848            throw new SecurityException("Requires permission "
10849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10850        }
10851
10852        Log.i(TAG, "Sending shutdown broadcast...");
10853
10854        BroadcastReceiver br = new BroadcastReceiver() {
10855            @Override public void onReceive(Context context, Intent intent) {
10856                // Now the broadcast is done, finish up the low-level shutdown.
10857                Log.i(TAG, "Shutting down activity manager...");
10858                shutdown(10000);
10859                Log.i(TAG, "Shutdown complete, restarting!");
10860                Process.killProcess(Process.myPid());
10861                System.exit(10);
10862            }
10863        };
10864
10865        // First send the high-level shut down broadcast.
10866        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10867        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10868        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10869        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10870        mContext.sendOrderedBroadcastAsUser(intent,
10871                UserHandle.ALL, null, br, mHandler, 0, null, null);
10872        */
10873        br.onReceive(mContext, intent);
10874    }
10875
10876    private long getLowRamTimeSinceIdle(long now) {
10877        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10878    }
10879
10880    @Override
10881    public void performIdleMaintenance() {
10882        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10883                != PackageManager.PERMISSION_GRANTED) {
10884            throw new SecurityException("Requires permission "
10885                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10886        }
10887
10888        synchronized (this) {
10889            final long now = SystemClock.uptimeMillis();
10890            final long timeSinceLastIdle = now - mLastIdleTime;
10891            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10892            mLastIdleTime = now;
10893            mLowRamTimeSinceLastIdle = 0;
10894            if (mLowRamStartTime != 0) {
10895                mLowRamStartTime = now;
10896            }
10897
10898            StringBuilder sb = new StringBuilder(128);
10899            sb.append("Idle maintenance over ");
10900            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10901            sb.append(" low RAM for ");
10902            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10903            Slog.i(TAG, sb.toString());
10904
10905            // If at least 1/3 of our time since the last idle period has been spent
10906            // with RAM low, then we want to kill processes.
10907            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10908
10909            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10910                ProcessRecord proc = mLruProcesses.get(i);
10911                if (proc.notCachedSinceIdle) {
10912                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10913                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10914                        if (doKilling && proc.initialIdlePss != 0
10915                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10916                            proc.kill("idle maint (pss " + proc.lastPss
10917                                    + " from " + proc.initialIdlePss + ")", true);
10918                        }
10919                    }
10920                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10921                    proc.notCachedSinceIdle = true;
10922                    proc.initialIdlePss = 0;
10923                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10924                            isSleeping(), now);
10925                }
10926            }
10927
10928            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10929            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10930        }
10931    }
10932
10933    private void retrieveSettings() {
10934        final ContentResolver resolver = mContext.getContentResolver();
10935        String debugApp = Settings.Global.getString(
10936            resolver, Settings.Global.DEBUG_APP);
10937        boolean waitForDebugger = Settings.Global.getInt(
10938            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10939        boolean alwaysFinishActivities = Settings.Global.getInt(
10940            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10941        boolean forceRtl = Settings.Global.getInt(
10942                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10943        // Transfer any global setting for forcing RTL layout, into a System Property
10944        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10945
10946        Configuration configuration = new Configuration();
10947        Settings.System.getConfiguration(resolver, configuration);
10948        if (forceRtl) {
10949            // This will take care of setting the correct layout direction flags
10950            configuration.setLayoutDirection(configuration.locale);
10951        }
10952
10953        synchronized (this) {
10954            mDebugApp = mOrigDebugApp = debugApp;
10955            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10956            mAlwaysFinishActivities = alwaysFinishActivities;
10957            // This happens before any activities are started, so we can
10958            // change mConfiguration in-place.
10959            updateConfigurationLocked(configuration, null, false, true);
10960            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10961        }
10962    }
10963
10964    /** Loads resources after the current configuration has been set. */
10965    private void loadResourcesOnSystemReady() {
10966        final Resources res = mContext.getResources();
10967        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10968        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10969        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10970    }
10971
10972    public boolean testIsSystemReady() {
10973        // no need to synchronize(this) just to read & return the value
10974        return mSystemReady;
10975    }
10976
10977    private static File getCalledPreBootReceiversFile() {
10978        File dataDir = Environment.getDataDirectory();
10979        File systemDir = new File(dataDir, "system");
10980        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10981        return fname;
10982    }
10983
10984    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10985        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10986        File file = getCalledPreBootReceiversFile();
10987        FileInputStream fis = null;
10988        try {
10989            fis = new FileInputStream(file);
10990            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10991            int fvers = dis.readInt();
10992            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10993                String vers = dis.readUTF();
10994                String codename = dis.readUTF();
10995                String build = dis.readUTF();
10996                if (android.os.Build.VERSION.RELEASE.equals(vers)
10997                        && android.os.Build.VERSION.CODENAME.equals(codename)
10998                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10999                    int num = dis.readInt();
11000                    while (num > 0) {
11001                        num--;
11002                        String pkg = dis.readUTF();
11003                        String cls = dis.readUTF();
11004                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11005                    }
11006                }
11007            }
11008        } catch (FileNotFoundException e) {
11009        } catch (IOException e) {
11010            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11011        } finally {
11012            if (fis != null) {
11013                try {
11014                    fis.close();
11015                } catch (IOException e) {
11016                }
11017            }
11018        }
11019        return lastDoneReceivers;
11020    }
11021
11022    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11023        File file = getCalledPreBootReceiversFile();
11024        FileOutputStream fos = null;
11025        DataOutputStream dos = null;
11026        try {
11027            fos = new FileOutputStream(file);
11028            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11029            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11030            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11031            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11032            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11033            dos.writeInt(list.size());
11034            for (int i=0; i<list.size(); i++) {
11035                dos.writeUTF(list.get(i).getPackageName());
11036                dos.writeUTF(list.get(i).getClassName());
11037            }
11038        } catch (IOException e) {
11039            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11040            file.delete();
11041        } finally {
11042            FileUtils.sync(fos);
11043            if (dos != null) {
11044                try {
11045                    dos.close();
11046                } catch (IOException e) {
11047                    // TODO Auto-generated catch block
11048                    e.printStackTrace();
11049                }
11050            }
11051        }
11052    }
11053
11054    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11055            ArrayList<ComponentName> doneReceivers, int userId) {
11056        boolean waitingUpdate = false;
11057        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11058        List<ResolveInfo> ris = null;
11059        try {
11060            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11061                    intent, null, 0, userId);
11062        } catch (RemoteException e) {
11063        }
11064        if (ris != null) {
11065            for (int i=ris.size()-1; i>=0; i--) {
11066                if ((ris.get(i).activityInfo.applicationInfo.flags
11067                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11068                    ris.remove(i);
11069                }
11070            }
11071            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11072
11073            // For User 0, load the version number. When delivering to a new user, deliver
11074            // to all receivers.
11075            if (userId == UserHandle.USER_OWNER) {
11076                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11077                for (int i=0; i<ris.size(); i++) {
11078                    ActivityInfo ai = ris.get(i).activityInfo;
11079                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11080                    if (lastDoneReceivers.contains(comp)) {
11081                        // We already did the pre boot receiver for this app with the current
11082                        // platform version, so don't do it again...
11083                        ris.remove(i);
11084                        i--;
11085                        // ...however, do keep it as one that has been done, so we don't
11086                        // forget about it when rewriting the file of last done receivers.
11087                        doneReceivers.add(comp);
11088                    }
11089                }
11090            }
11091
11092            // If primary user, send broadcast to all available users, else just to userId
11093            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11094                    : new int[] { userId };
11095            for (int i = 0; i < ris.size(); i++) {
11096                ActivityInfo ai = ris.get(i).activityInfo;
11097                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11098                doneReceivers.add(comp);
11099                intent.setComponent(comp);
11100                for (int j=0; j<users.length; j++) {
11101                    IIntentReceiver finisher = null;
11102                    // On last receiver and user, set up a completion callback
11103                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11104                        finisher = new IIntentReceiver.Stub() {
11105                            public void performReceive(Intent intent, int resultCode,
11106                                    String data, Bundle extras, boolean ordered,
11107                                    boolean sticky, int sendingUser) {
11108                                // The raw IIntentReceiver interface is called
11109                                // with the AM lock held, so redispatch to
11110                                // execute our code without the lock.
11111                                mHandler.post(onFinishCallback);
11112                            }
11113                        };
11114                    }
11115                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11116                            + " for user " + users[j]);
11117                    broadcastIntentLocked(null, null, intent, null, finisher,
11118                            0, null, null, null, AppOpsManager.OP_NONE,
11119                            true, false, MY_PID, Process.SYSTEM_UID,
11120                            users[j]);
11121                    if (finisher != null) {
11122                        waitingUpdate = true;
11123                    }
11124                }
11125            }
11126        }
11127
11128        return waitingUpdate;
11129    }
11130
11131    public void systemReady(final Runnable goingCallback) {
11132        synchronized(this) {
11133            if (mSystemReady) {
11134                // If we're done calling all the receivers, run the next "boot phase" passed in
11135                // by the SystemServer
11136                if (goingCallback != null) {
11137                    goingCallback.run();
11138                }
11139                return;
11140            }
11141
11142            // Make sure we have the current profile info, since it is needed for
11143            // security checks.
11144            updateCurrentProfileIdsLocked();
11145
11146            if (mRecentTasks == null) {
11147                mRecentTasks = mTaskPersister.restoreTasksLocked();
11148                if (!mRecentTasks.isEmpty()) {
11149                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11150                }
11151                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11152                mTaskPersister.startPersisting();
11153            }
11154
11155            // Check to see if there are any update receivers to run.
11156            if (!mDidUpdate) {
11157                if (mWaitingUpdate) {
11158                    return;
11159                }
11160                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11161                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11162                    public void run() {
11163                        synchronized (ActivityManagerService.this) {
11164                            mDidUpdate = true;
11165                        }
11166                        writeLastDonePreBootReceivers(doneReceivers);
11167                        showBootMessage(mContext.getText(
11168                                R.string.android_upgrading_complete),
11169                                false);
11170                        systemReady(goingCallback);
11171                    }
11172                }, doneReceivers, UserHandle.USER_OWNER);
11173
11174                if (mWaitingUpdate) {
11175                    return;
11176                }
11177                mDidUpdate = true;
11178            }
11179
11180            mAppOpsService.systemReady();
11181            mSystemReady = true;
11182        }
11183
11184        ArrayList<ProcessRecord> procsToKill = null;
11185        synchronized(mPidsSelfLocked) {
11186            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11187                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11188                if (!isAllowedWhileBooting(proc.info)){
11189                    if (procsToKill == null) {
11190                        procsToKill = new ArrayList<ProcessRecord>();
11191                    }
11192                    procsToKill.add(proc);
11193                }
11194            }
11195        }
11196
11197        synchronized(this) {
11198            if (procsToKill != null) {
11199                for (int i=procsToKill.size()-1; i>=0; i--) {
11200                    ProcessRecord proc = procsToKill.get(i);
11201                    Slog.i(TAG, "Removing system update proc: " + proc);
11202                    removeProcessLocked(proc, true, false, "system update done");
11203                }
11204            }
11205
11206            // Now that we have cleaned up any update processes, we
11207            // are ready to start launching real processes and know that
11208            // we won't trample on them any more.
11209            mProcessesReady = true;
11210        }
11211
11212        Slog.i(TAG, "System now ready");
11213        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11214            SystemClock.uptimeMillis());
11215
11216        synchronized(this) {
11217            // Make sure we have no pre-ready processes sitting around.
11218
11219            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11220                ResolveInfo ri = mContext.getPackageManager()
11221                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11222                                STOCK_PM_FLAGS);
11223                CharSequence errorMsg = null;
11224                if (ri != null) {
11225                    ActivityInfo ai = ri.activityInfo;
11226                    ApplicationInfo app = ai.applicationInfo;
11227                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11228                        mTopAction = Intent.ACTION_FACTORY_TEST;
11229                        mTopData = null;
11230                        mTopComponent = new ComponentName(app.packageName,
11231                                ai.name);
11232                    } else {
11233                        errorMsg = mContext.getResources().getText(
11234                                com.android.internal.R.string.factorytest_not_system);
11235                    }
11236                } else {
11237                    errorMsg = mContext.getResources().getText(
11238                            com.android.internal.R.string.factorytest_no_action);
11239                }
11240                if (errorMsg != null) {
11241                    mTopAction = null;
11242                    mTopData = null;
11243                    mTopComponent = null;
11244                    Message msg = Message.obtain();
11245                    msg.what = SHOW_FACTORY_ERROR_MSG;
11246                    msg.getData().putCharSequence("msg", errorMsg);
11247                    mHandler.sendMessage(msg);
11248                }
11249            }
11250        }
11251
11252        retrieveSettings();
11253        loadResourcesOnSystemReady();
11254
11255        synchronized (this) {
11256            readGrantedUriPermissionsLocked();
11257        }
11258
11259        if (goingCallback != null) goingCallback.run();
11260
11261        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11262                Integer.toString(mCurrentUserId), mCurrentUserId);
11263        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11264                Integer.toString(mCurrentUserId), mCurrentUserId);
11265        mSystemServiceManager.startUser(mCurrentUserId);
11266
11267        synchronized (this) {
11268            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11269                try {
11270                    List apps = AppGlobals.getPackageManager().
11271                        getPersistentApplications(STOCK_PM_FLAGS);
11272                    if (apps != null) {
11273                        int N = apps.size();
11274                        int i;
11275                        for (i=0; i<N; i++) {
11276                            ApplicationInfo info
11277                                = (ApplicationInfo)apps.get(i);
11278                            if (info != null &&
11279                                    !info.packageName.equals("android")) {
11280                                addAppLocked(info, false, null /* ABI override */);
11281                            }
11282                        }
11283                    }
11284                } catch (RemoteException ex) {
11285                    // pm is in same process, this will never happen.
11286                }
11287            }
11288
11289            // Start up initial activity.
11290            mBooting = true;
11291            startHomeActivityLocked(mCurrentUserId);
11292
11293            try {
11294                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11295                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11296                            + " data partition or your device will be unstable.");
11297                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11298                }
11299            } catch (RemoteException e) {
11300            }
11301
11302            if (!Build.isFingerprintConsistent()) {
11303                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11304                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11305            }
11306
11307            long ident = Binder.clearCallingIdentity();
11308            try {
11309                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11310                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11311                        | Intent.FLAG_RECEIVER_FOREGROUND);
11312                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11313                broadcastIntentLocked(null, null, intent,
11314                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11315                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11316                intent = new Intent(Intent.ACTION_USER_STARTING);
11317                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11318                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11319                broadcastIntentLocked(null, null, intent,
11320                        null, new IIntentReceiver.Stub() {
11321                            @Override
11322                            public void performReceive(Intent intent, int resultCode, String data,
11323                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11324                                    throws RemoteException {
11325                            }
11326                        }, 0, null, null,
11327                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11328                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11329            } catch (Throwable t) {
11330                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11331            } finally {
11332                Binder.restoreCallingIdentity(ident);
11333            }
11334            mStackSupervisor.resumeTopActivitiesLocked();
11335            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11336        }
11337    }
11338
11339    private boolean makeAppCrashingLocked(ProcessRecord app,
11340            String shortMsg, String longMsg, String stackTrace) {
11341        app.crashing = true;
11342        app.crashingReport = generateProcessError(app,
11343                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11344        startAppProblemLocked(app);
11345        app.stopFreezingAllLocked();
11346        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11347    }
11348
11349    private void makeAppNotRespondingLocked(ProcessRecord app,
11350            String activity, String shortMsg, String longMsg) {
11351        app.notResponding = true;
11352        app.notRespondingReport = generateProcessError(app,
11353                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11354                activity, shortMsg, longMsg, null);
11355        startAppProblemLocked(app);
11356        app.stopFreezingAllLocked();
11357    }
11358
11359    /**
11360     * Generate a process error record, suitable for attachment to a ProcessRecord.
11361     *
11362     * @param app The ProcessRecord in which the error occurred.
11363     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11364     *                      ActivityManager.AppErrorStateInfo
11365     * @param activity The activity associated with the crash, if known.
11366     * @param shortMsg Short message describing the crash.
11367     * @param longMsg Long message describing the crash.
11368     * @param stackTrace Full crash stack trace, may be null.
11369     *
11370     * @return Returns a fully-formed AppErrorStateInfo record.
11371     */
11372    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11373            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11374        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11375
11376        report.condition = condition;
11377        report.processName = app.processName;
11378        report.pid = app.pid;
11379        report.uid = app.info.uid;
11380        report.tag = activity;
11381        report.shortMsg = shortMsg;
11382        report.longMsg = longMsg;
11383        report.stackTrace = stackTrace;
11384
11385        return report;
11386    }
11387
11388    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11389        synchronized (this) {
11390            app.crashing = false;
11391            app.crashingReport = null;
11392            app.notResponding = false;
11393            app.notRespondingReport = null;
11394            if (app.anrDialog == fromDialog) {
11395                app.anrDialog = null;
11396            }
11397            if (app.waitDialog == fromDialog) {
11398                app.waitDialog = null;
11399            }
11400            if (app.pid > 0 && app.pid != MY_PID) {
11401                handleAppCrashLocked(app, null, null, null);
11402                app.kill("user request after error", true);
11403            }
11404        }
11405    }
11406
11407    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11408            String stackTrace) {
11409        long now = SystemClock.uptimeMillis();
11410
11411        Long crashTime;
11412        if (!app.isolated) {
11413            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11414        } else {
11415            crashTime = null;
11416        }
11417        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11418            // This process loses!
11419            Slog.w(TAG, "Process " + app.info.processName
11420                    + " has crashed too many times: killing!");
11421            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11422                    app.userId, app.info.processName, app.uid);
11423            mStackSupervisor.handleAppCrashLocked(app);
11424            if (!app.persistent) {
11425                // We don't want to start this process again until the user
11426                // explicitly does so...  but for persistent process, we really
11427                // need to keep it running.  If a persistent process is actually
11428                // repeatedly crashing, then badness for everyone.
11429                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11430                        app.info.processName);
11431                if (!app.isolated) {
11432                    // XXX We don't have a way to mark isolated processes
11433                    // as bad, since they don't have a peristent identity.
11434                    mBadProcesses.put(app.info.processName, app.uid,
11435                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11436                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11437                }
11438                app.bad = true;
11439                app.removed = true;
11440                // Don't let services in this process be restarted and potentially
11441                // annoy the user repeatedly.  Unless it is persistent, since those
11442                // processes run critical code.
11443                removeProcessLocked(app, false, false, "crash");
11444                mStackSupervisor.resumeTopActivitiesLocked();
11445                return false;
11446            }
11447            mStackSupervisor.resumeTopActivitiesLocked();
11448        } else {
11449            mStackSupervisor.finishTopRunningActivityLocked(app);
11450        }
11451
11452        // Bump up the crash count of any services currently running in the proc.
11453        for (int i=app.services.size()-1; i>=0; i--) {
11454            // Any services running in the application need to be placed
11455            // back in the pending list.
11456            ServiceRecord sr = app.services.valueAt(i);
11457            sr.crashCount++;
11458        }
11459
11460        // If the crashing process is what we consider to be the "home process" and it has been
11461        // replaced by a third-party app, clear the package preferred activities from packages
11462        // with a home activity running in the process to prevent a repeatedly crashing app
11463        // from blocking the user to manually clear the list.
11464        final ArrayList<ActivityRecord> activities = app.activities;
11465        if (app == mHomeProcess && activities.size() > 0
11466                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11467            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11468                final ActivityRecord r = activities.get(activityNdx);
11469                if (r.isHomeActivity()) {
11470                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11471                    try {
11472                        ActivityThread.getPackageManager()
11473                                .clearPackagePreferredActivities(r.packageName);
11474                    } catch (RemoteException c) {
11475                        // pm is in same process, this will never happen.
11476                    }
11477                }
11478            }
11479        }
11480
11481        if (!app.isolated) {
11482            // XXX Can't keep track of crash times for isolated processes,
11483            // because they don't have a perisistent identity.
11484            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11485        }
11486
11487        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11488        return true;
11489    }
11490
11491    void startAppProblemLocked(ProcessRecord app) {
11492        // If this app is not running under the current user, then we
11493        // can't give it a report button because that would require
11494        // launching the report UI under a different user.
11495        app.errorReportReceiver = null;
11496
11497        for (int userId : mCurrentProfileIds) {
11498            if (app.userId == userId) {
11499                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11500                        mContext, app.info.packageName, app.info.flags);
11501            }
11502        }
11503        skipCurrentReceiverLocked(app);
11504    }
11505
11506    void skipCurrentReceiverLocked(ProcessRecord app) {
11507        for (BroadcastQueue queue : mBroadcastQueues) {
11508            queue.skipCurrentReceiverLocked(app);
11509        }
11510    }
11511
11512    /**
11513     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11514     * The application process will exit immediately after this call returns.
11515     * @param app object of the crashing app, null for the system server
11516     * @param crashInfo describing the exception
11517     */
11518    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11519        ProcessRecord r = findAppProcess(app, "Crash");
11520        final String processName = app == null ? "system_server"
11521                : (r == null ? "unknown" : r.processName);
11522
11523        handleApplicationCrashInner("crash", r, processName, crashInfo);
11524    }
11525
11526    /* Native crash reporting uses this inner version because it needs to be somewhat
11527     * decoupled from the AM-managed cleanup lifecycle
11528     */
11529    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11530            ApplicationErrorReport.CrashInfo crashInfo) {
11531        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11532                UserHandle.getUserId(Binder.getCallingUid()), processName,
11533                r == null ? -1 : r.info.flags,
11534                crashInfo.exceptionClassName,
11535                crashInfo.exceptionMessage,
11536                crashInfo.throwFileName,
11537                crashInfo.throwLineNumber);
11538
11539        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11540
11541        crashApplication(r, crashInfo);
11542    }
11543
11544    public void handleApplicationStrictModeViolation(
11545            IBinder app,
11546            int violationMask,
11547            StrictMode.ViolationInfo info) {
11548        ProcessRecord r = findAppProcess(app, "StrictMode");
11549        if (r == null) {
11550            return;
11551        }
11552
11553        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11554            Integer stackFingerprint = info.hashCode();
11555            boolean logIt = true;
11556            synchronized (mAlreadyLoggedViolatedStacks) {
11557                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11558                    logIt = false;
11559                    // TODO: sub-sample into EventLog for these, with
11560                    // the info.durationMillis?  Then we'd get
11561                    // the relative pain numbers, without logging all
11562                    // the stack traces repeatedly.  We'd want to do
11563                    // likewise in the client code, which also does
11564                    // dup suppression, before the Binder call.
11565                } else {
11566                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11567                        mAlreadyLoggedViolatedStacks.clear();
11568                    }
11569                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11570                }
11571            }
11572            if (logIt) {
11573                logStrictModeViolationToDropBox(r, info);
11574            }
11575        }
11576
11577        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11578            AppErrorResult result = new AppErrorResult();
11579            synchronized (this) {
11580                final long origId = Binder.clearCallingIdentity();
11581
11582                Message msg = Message.obtain();
11583                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11584                HashMap<String, Object> data = new HashMap<String, Object>();
11585                data.put("result", result);
11586                data.put("app", r);
11587                data.put("violationMask", violationMask);
11588                data.put("info", info);
11589                msg.obj = data;
11590                mHandler.sendMessage(msg);
11591
11592                Binder.restoreCallingIdentity(origId);
11593            }
11594            int res = result.get();
11595            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11596        }
11597    }
11598
11599    // Depending on the policy in effect, there could be a bunch of
11600    // these in quick succession so we try to batch these together to
11601    // minimize disk writes, number of dropbox entries, and maximize
11602    // compression, by having more fewer, larger records.
11603    private void logStrictModeViolationToDropBox(
11604            ProcessRecord process,
11605            StrictMode.ViolationInfo info) {
11606        if (info == null) {
11607            return;
11608        }
11609        final boolean isSystemApp = process == null ||
11610                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11611                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11612        final String processName = process == null ? "unknown" : process.processName;
11613        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11614        final DropBoxManager dbox = (DropBoxManager)
11615                mContext.getSystemService(Context.DROPBOX_SERVICE);
11616
11617        // Exit early if the dropbox isn't configured to accept this report type.
11618        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11619
11620        boolean bufferWasEmpty;
11621        boolean needsFlush;
11622        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11623        synchronized (sb) {
11624            bufferWasEmpty = sb.length() == 0;
11625            appendDropBoxProcessHeaders(process, processName, sb);
11626            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11627            sb.append("System-App: ").append(isSystemApp).append("\n");
11628            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11629            if (info.violationNumThisLoop != 0) {
11630                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11631            }
11632            if (info.numAnimationsRunning != 0) {
11633                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11634            }
11635            if (info.broadcastIntentAction != null) {
11636                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11637            }
11638            if (info.durationMillis != -1) {
11639                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11640            }
11641            if (info.numInstances != -1) {
11642                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11643            }
11644            if (info.tags != null) {
11645                for (String tag : info.tags) {
11646                    sb.append("Span-Tag: ").append(tag).append("\n");
11647                }
11648            }
11649            sb.append("\n");
11650            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11651                sb.append(info.crashInfo.stackTrace);
11652            }
11653            sb.append("\n");
11654
11655            // Only buffer up to ~64k.  Various logging bits truncate
11656            // things at 128k.
11657            needsFlush = (sb.length() > 64 * 1024);
11658        }
11659
11660        // Flush immediately if the buffer's grown too large, or this
11661        // is a non-system app.  Non-system apps are isolated with a
11662        // different tag & policy and not batched.
11663        //
11664        // Batching is useful during internal testing with
11665        // StrictMode settings turned up high.  Without batching,
11666        // thousands of separate files could be created on boot.
11667        if (!isSystemApp || needsFlush) {
11668            new Thread("Error dump: " + dropboxTag) {
11669                @Override
11670                public void run() {
11671                    String report;
11672                    synchronized (sb) {
11673                        report = sb.toString();
11674                        sb.delete(0, sb.length());
11675                        sb.trimToSize();
11676                    }
11677                    if (report.length() != 0) {
11678                        dbox.addText(dropboxTag, report);
11679                    }
11680                }
11681            }.start();
11682            return;
11683        }
11684
11685        // System app batching:
11686        if (!bufferWasEmpty) {
11687            // An existing dropbox-writing thread is outstanding, so
11688            // we don't need to start it up.  The existing thread will
11689            // catch the buffer appends we just did.
11690            return;
11691        }
11692
11693        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11694        // (After this point, we shouldn't access AMS internal data structures.)
11695        new Thread("Error dump: " + dropboxTag) {
11696            @Override
11697            public void run() {
11698                // 5 second sleep to let stacks arrive and be batched together
11699                try {
11700                    Thread.sleep(5000);  // 5 seconds
11701                } catch (InterruptedException e) {}
11702
11703                String errorReport;
11704                synchronized (mStrictModeBuffer) {
11705                    errorReport = mStrictModeBuffer.toString();
11706                    if (errorReport.length() == 0) {
11707                        return;
11708                    }
11709                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11710                    mStrictModeBuffer.trimToSize();
11711                }
11712                dbox.addText(dropboxTag, errorReport);
11713            }
11714        }.start();
11715    }
11716
11717    /**
11718     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11719     * @param app object of the crashing app, null for the system server
11720     * @param tag reported by the caller
11721     * @param system whether this wtf is coming from the system
11722     * @param crashInfo describing the context of the error
11723     * @return true if the process should exit immediately (WTF is fatal)
11724     */
11725    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11726            final ApplicationErrorReport.CrashInfo crashInfo) {
11727        final int callingUid = Binder.getCallingUid();
11728        final int callingPid = Binder.getCallingPid();
11729
11730        if (system) {
11731            // If this is coming from the system, we could very well have low-level
11732            // system locks held, so we want to do this all asynchronously.  And we
11733            // never want this to become fatal, so there is that too.
11734            mHandler.post(new Runnable() {
11735                @Override public void run() {
11736                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11737                }
11738            });
11739            return false;
11740        }
11741
11742        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11743                crashInfo);
11744
11745        if (r != null && r.pid != Process.myPid() &&
11746                Settings.Global.getInt(mContext.getContentResolver(),
11747                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11748            crashApplication(r, crashInfo);
11749            return true;
11750        } else {
11751            return false;
11752        }
11753    }
11754
11755    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11756            final ApplicationErrorReport.CrashInfo crashInfo) {
11757        final ProcessRecord r = findAppProcess(app, "WTF");
11758        final String processName = app == null ? "system_server"
11759                : (r == null ? "unknown" : r.processName);
11760
11761        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11762                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11763
11764        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11765
11766        return r;
11767    }
11768
11769    /**
11770     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11771     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11772     */
11773    private ProcessRecord findAppProcess(IBinder app, String reason) {
11774        if (app == null) {
11775            return null;
11776        }
11777
11778        synchronized (this) {
11779            final int NP = mProcessNames.getMap().size();
11780            for (int ip=0; ip<NP; ip++) {
11781                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11782                final int NA = apps.size();
11783                for (int ia=0; ia<NA; ia++) {
11784                    ProcessRecord p = apps.valueAt(ia);
11785                    if (p.thread != null && p.thread.asBinder() == app) {
11786                        return p;
11787                    }
11788                }
11789            }
11790
11791            Slog.w(TAG, "Can't find mystery application for " + reason
11792                    + " from pid=" + Binder.getCallingPid()
11793                    + " uid=" + Binder.getCallingUid() + ": " + app);
11794            return null;
11795        }
11796    }
11797
11798    /**
11799     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11800     * to append various headers to the dropbox log text.
11801     */
11802    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11803            StringBuilder sb) {
11804        // Watchdog thread ends up invoking this function (with
11805        // a null ProcessRecord) to add the stack file to dropbox.
11806        // Do not acquire a lock on this (am) in such cases, as it
11807        // could cause a potential deadlock, if and when watchdog
11808        // is invoked due to unavailability of lock on am and it
11809        // would prevent watchdog from killing system_server.
11810        if (process == null) {
11811            sb.append("Process: ").append(processName).append("\n");
11812            return;
11813        }
11814        // Note: ProcessRecord 'process' is guarded by the service
11815        // instance.  (notably process.pkgList, which could otherwise change
11816        // concurrently during execution of this method)
11817        synchronized (this) {
11818            sb.append("Process: ").append(processName).append("\n");
11819            int flags = process.info.flags;
11820            IPackageManager pm = AppGlobals.getPackageManager();
11821            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11822            for (int ip=0; ip<process.pkgList.size(); ip++) {
11823                String pkg = process.pkgList.keyAt(ip);
11824                sb.append("Package: ").append(pkg);
11825                try {
11826                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11827                    if (pi != null) {
11828                        sb.append(" v").append(pi.versionCode);
11829                        if (pi.versionName != null) {
11830                            sb.append(" (").append(pi.versionName).append(")");
11831                        }
11832                    }
11833                } catch (RemoteException e) {
11834                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11835                }
11836                sb.append("\n");
11837            }
11838        }
11839    }
11840
11841    private static String processClass(ProcessRecord process) {
11842        if (process == null || process.pid == MY_PID) {
11843            return "system_server";
11844        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11845            return "system_app";
11846        } else {
11847            return "data_app";
11848        }
11849    }
11850
11851    /**
11852     * Write a description of an error (crash, WTF, ANR) to the drop box.
11853     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11854     * @param process which caused the error, null means the system server
11855     * @param activity which triggered the error, null if unknown
11856     * @param parent activity related to the error, null if unknown
11857     * @param subject line related to the error, null if absent
11858     * @param report in long form describing the error, null if absent
11859     * @param logFile to include in the report, null if none
11860     * @param crashInfo giving an application stack trace, null if absent
11861     */
11862    public void addErrorToDropBox(String eventType,
11863            ProcessRecord process, String processName, ActivityRecord activity,
11864            ActivityRecord parent, String subject,
11865            final String report, final File logFile,
11866            final ApplicationErrorReport.CrashInfo crashInfo) {
11867        // NOTE -- this must never acquire the ActivityManagerService lock,
11868        // otherwise the watchdog may be prevented from resetting the system.
11869
11870        final String dropboxTag = processClass(process) + "_" + eventType;
11871        final DropBoxManager dbox = (DropBoxManager)
11872                mContext.getSystemService(Context.DROPBOX_SERVICE);
11873
11874        // Exit early if the dropbox isn't configured to accept this report type.
11875        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11876
11877        final StringBuilder sb = new StringBuilder(1024);
11878        appendDropBoxProcessHeaders(process, processName, sb);
11879        if (activity != null) {
11880            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11881        }
11882        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11883            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11884        }
11885        if (parent != null && parent != activity) {
11886            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11887        }
11888        if (subject != null) {
11889            sb.append("Subject: ").append(subject).append("\n");
11890        }
11891        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11892        if (Debug.isDebuggerConnected()) {
11893            sb.append("Debugger: Connected\n");
11894        }
11895        sb.append("\n");
11896
11897        // Do the rest in a worker thread to avoid blocking the caller on I/O
11898        // (After this point, we shouldn't access AMS internal data structures.)
11899        Thread worker = new Thread("Error dump: " + dropboxTag) {
11900            @Override
11901            public void run() {
11902                if (report != null) {
11903                    sb.append(report);
11904                }
11905                if (logFile != null) {
11906                    try {
11907                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11908                                    "\n\n[[TRUNCATED]]"));
11909                    } catch (IOException e) {
11910                        Slog.e(TAG, "Error reading " + logFile, e);
11911                    }
11912                }
11913                if (crashInfo != null && crashInfo.stackTrace != null) {
11914                    sb.append(crashInfo.stackTrace);
11915                }
11916
11917                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11918                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11919                if (lines > 0) {
11920                    sb.append("\n");
11921
11922                    // Merge several logcat streams, and take the last N lines
11923                    InputStreamReader input = null;
11924                    try {
11925                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11926                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11927                                "-b", "crash",
11928                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11929
11930                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11931                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11932                        input = new InputStreamReader(logcat.getInputStream());
11933
11934                        int num;
11935                        char[] buf = new char[8192];
11936                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11937                    } catch (IOException e) {
11938                        Slog.e(TAG, "Error running logcat", e);
11939                    } finally {
11940                        if (input != null) try { input.close(); } catch (IOException e) {}
11941                    }
11942                }
11943
11944                dbox.addText(dropboxTag, sb.toString());
11945            }
11946        };
11947
11948        if (process == null) {
11949            // If process is null, we are being called from some internal code
11950            // and may be about to die -- run this synchronously.
11951            worker.run();
11952        } else {
11953            worker.start();
11954        }
11955    }
11956
11957    /**
11958     * Bring up the "unexpected error" dialog box for a crashing app.
11959     * Deal with edge cases (intercepts from instrumented applications,
11960     * ActivityController, error intent receivers, that sort of thing).
11961     * @param r the application crashing
11962     * @param crashInfo describing the failure
11963     */
11964    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11965        long timeMillis = System.currentTimeMillis();
11966        String shortMsg = crashInfo.exceptionClassName;
11967        String longMsg = crashInfo.exceptionMessage;
11968        String stackTrace = crashInfo.stackTrace;
11969        if (shortMsg != null && longMsg != null) {
11970            longMsg = shortMsg + ": " + longMsg;
11971        } else if (shortMsg != null) {
11972            longMsg = shortMsg;
11973        }
11974
11975        AppErrorResult result = new AppErrorResult();
11976        synchronized (this) {
11977            if (mController != null) {
11978                try {
11979                    String name = r != null ? r.processName : null;
11980                    int pid = r != null ? r.pid : Binder.getCallingPid();
11981                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11982                    if (!mController.appCrashed(name, pid,
11983                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11984                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11985                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11986                            Slog.w(TAG, "Skip killing native crashed app " + name
11987                                    + "(" + pid + ") during testing");
11988                        } else {
11989                            Slog.w(TAG, "Force-killing crashed app " + name
11990                                    + " at watcher's request");
11991                            if (r != null) {
11992                                r.kill("crash", true);
11993                            } else {
11994                                // Huh.
11995                                Process.killProcess(pid);
11996                                Process.killProcessGroup(uid, pid);
11997                            }
11998                        }
11999                        return;
12000                    }
12001                } catch (RemoteException e) {
12002                    mController = null;
12003                    Watchdog.getInstance().setActivityController(null);
12004                }
12005            }
12006
12007            final long origId = Binder.clearCallingIdentity();
12008
12009            // If this process is running instrumentation, finish it.
12010            if (r != null && r.instrumentationClass != null) {
12011                Slog.w(TAG, "Error in app " + r.processName
12012                      + " running instrumentation " + r.instrumentationClass + ":");
12013                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12014                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12015                Bundle info = new Bundle();
12016                info.putString("shortMsg", shortMsg);
12017                info.putString("longMsg", longMsg);
12018                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12019                Binder.restoreCallingIdentity(origId);
12020                return;
12021            }
12022
12023            // If we can't identify the process or it's already exceeded its crash quota,
12024            // quit right away without showing a crash dialog.
12025            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12026                Binder.restoreCallingIdentity(origId);
12027                return;
12028            }
12029
12030            Message msg = Message.obtain();
12031            msg.what = SHOW_ERROR_MSG;
12032            HashMap data = new HashMap();
12033            data.put("result", result);
12034            data.put("app", r);
12035            msg.obj = data;
12036            mHandler.sendMessage(msg);
12037
12038            Binder.restoreCallingIdentity(origId);
12039        }
12040
12041        int res = result.get();
12042
12043        Intent appErrorIntent = null;
12044        synchronized (this) {
12045            if (r != null && !r.isolated) {
12046                // XXX Can't keep track of crash time for isolated processes,
12047                // since they don't have a persistent identity.
12048                mProcessCrashTimes.put(r.info.processName, r.uid,
12049                        SystemClock.uptimeMillis());
12050            }
12051            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12052                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12053            }
12054        }
12055
12056        if (appErrorIntent != null) {
12057            try {
12058                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12059            } catch (ActivityNotFoundException e) {
12060                Slog.w(TAG, "bug report receiver dissappeared", e);
12061            }
12062        }
12063    }
12064
12065    Intent createAppErrorIntentLocked(ProcessRecord r,
12066            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12067        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12068        if (report == null) {
12069            return null;
12070        }
12071        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12072        result.setComponent(r.errorReportReceiver);
12073        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12074        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12075        return result;
12076    }
12077
12078    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12079            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12080        if (r.errorReportReceiver == null) {
12081            return null;
12082        }
12083
12084        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12085            return null;
12086        }
12087
12088        ApplicationErrorReport report = new ApplicationErrorReport();
12089        report.packageName = r.info.packageName;
12090        report.installerPackageName = r.errorReportReceiver.getPackageName();
12091        report.processName = r.processName;
12092        report.time = timeMillis;
12093        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12094
12095        if (r.crashing || r.forceCrashReport) {
12096            report.type = ApplicationErrorReport.TYPE_CRASH;
12097            report.crashInfo = crashInfo;
12098        } else if (r.notResponding) {
12099            report.type = ApplicationErrorReport.TYPE_ANR;
12100            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12101
12102            report.anrInfo.activity = r.notRespondingReport.tag;
12103            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12104            report.anrInfo.info = r.notRespondingReport.longMsg;
12105        }
12106
12107        return report;
12108    }
12109
12110    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12111        enforceNotIsolatedCaller("getProcessesInErrorState");
12112        // assume our apps are happy - lazy create the list
12113        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12114
12115        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12116                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12117        int userId = UserHandle.getUserId(Binder.getCallingUid());
12118
12119        synchronized (this) {
12120
12121            // iterate across all processes
12122            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12123                ProcessRecord app = mLruProcesses.get(i);
12124                if (!allUsers && app.userId != userId) {
12125                    continue;
12126                }
12127                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12128                    // This one's in trouble, so we'll generate a report for it
12129                    // crashes are higher priority (in case there's a crash *and* an anr)
12130                    ActivityManager.ProcessErrorStateInfo report = null;
12131                    if (app.crashing) {
12132                        report = app.crashingReport;
12133                    } else if (app.notResponding) {
12134                        report = app.notRespondingReport;
12135                    }
12136
12137                    if (report != null) {
12138                        if (errList == null) {
12139                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12140                        }
12141                        errList.add(report);
12142                    } else {
12143                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12144                                " crashing = " + app.crashing +
12145                                " notResponding = " + app.notResponding);
12146                    }
12147                }
12148            }
12149        }
12150
12151        return errList;
12152    }
12153
12154    static int procStateToImportance(int procState, int memAdj,
12155            ActivityManager.RunningAppProcessInfo currApp) {
12156        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12157        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12158            currApp.lru = memAdj;
12159        } else {
12160            currApp.lru = 0;
12161        }
12162        return imp;
12163    }
12164
12165    private void fillInProcMemInfo(ProcessRecord app,
12166            ActivityManager.RunningAppProcessInfo outInfo) {
12167        outInfo.pid = app.pid;
12168        outInfo.uid = app.info.uid;
12169        if (mHeavyWeightProcess == app) {
12170            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12171        }
12172        if (app.persistent) {
12173            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12174        }
12175        if (app.activities.size() > 0) {
12176            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12177        }
12178        outInfo.lastTrimLevel = app.trimMemoryLevel;
12179        int adj = app.curAdj;
12180        int procState = app.curProcState;
12181        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12182        outInfo.importanceReasonCode = app.adjTypeCode;
12183        outInfo.processState = app.curProcState;
12184    }
12185
12186    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12187        enforceNotIsolatedCaller("getRunningAppProcesses");
12188        // Lazy instantiation of list
12189        List<ActivityManager.RunningAppProcessInfo> runList = null;
12190        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12191                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12192        int userId = UserHandle.getUserId(Binder.getCallingUid());
12193        synchronized (this) {
12194            // Iterate across all processes
12195            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12196                ProcessRecord app = mLruProcesses.get(i);
12197                if (!allUsers && app.userId != userId) {
12198                    continue;
12199                }
12200                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12201                    // Generate process state info for running application
12202                    ActivityManager.RunningAppProcessInfo currApp =
12203                        new ActivityManager.RunningAppProcessInfo(app.processName,
12204                                app.pid, app.getPackageList());
12205                    fillInProcMemInfo(app, currApp);
12206                    if (app.adjSource instanceof ProcessRecord) {
12207                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12208                        currApp.importanceReasonImportance =
12209                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12210                                        app.adjSourceProcState);
12211                    } else if (app.adjSource instanceof ActivityRecord) {
12212                        ActivityRecord r = (ActivityRecord)app.adjSource;
12213                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12214                    }
12215                    if (app.adjTarget instanceof ComponentName) {
12216                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12217                    }
12218                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12219                    //        + " lru=" + currApp.lru);
12220                    if (runList == null) {
12221                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12222                    }
12223                    runList.add(currApp);
12224                }
12225            }
12226        }
12227        return runList;
12228    }
12229
12230    public List<ApplicationInfo> getRunningExternalApplications() {
12231        enforceNotIsolatedCaller("getRunningExternalApplications");
12232        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12233        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12234        if (runningApps != null && runningApps.size() > 0) {
12235            Set<String> extList = new HashSet<String>();
12236            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12237                if (app.pkgList != null) {
12238                    for (String pkg : app.pkgList) {
12239                        extList.add(pkg);
12240                    }
12241                }
12242            }
12243            IPackageManager pm = AppGlobals.getPackageManager();
12244            for (String pkg : extList) {
12245                try {
12246                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12247                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12248                        retList.add(info);
12249                    }
12250                } catch (RemoteException e) {
12251                }
12252            }
12253        }
12254        return retList;
12255    }
12256
12257    @Override
12258    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12259        enforceNotIsolatedCaller("getMyMemoryState");
12260        synchronized (this) {
12261            ProcessRecord proc;
12262            synchronized (mPidsSelfLocked) {
12263                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12264            }
12265            fillInProcMemInfo(proc, outInfo);
12266        }
12267    }
12268
12269    @Override
12270    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12271        if (checkCallingPermission(android.Manifest.permission.DUMP)
12272                != PackageManager.PERMISSION_GRANTED) {
12273            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12274                    + Binder.getCallingPid()
12275                    + ", uid=" + Binder.getCallingUid()
12276                    + " without permission "
12277                    + android.Manifest.permission.DUMP);
12278            return;
12279        }
12280
12281        boolean dumpAll = false;
12282        boolean dumpClient = false;
12283        String dumpPackage = null;
12284
12285        int opti = 0;
12286        while (opti < args.length) {
12287            String opt = args[opti];
12288            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12289                break;
12290            }
12291            opti++;
12292            if ("-a".equals(opt)) {
12293                dumpAll = true;
12294            } else if ("-c".equals(opt)) {
12295                dumpClient = true;
12296            } else if ("-h".equals(opt)) {
12297                pw.println("Activity manager dump options:");
12298                pw.println("  [-a] [-c] [-h] [cmd] ...");
12299                pw.println("  cmd may be one of:");
12300                pw.println("    a[ctivities]: activity stack state");
12301                pw.println("    r[recents]: recent activities state");
12302                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12303                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12304                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12305                pw.println("    o[om]: out of memory management");
12306                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12307                pw.println("    provider [COMP_SPEC]: provider client-side state");
12308                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12309                pw.println("    service [COMP_SPEC]: service client-side state");
12310                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12311                pw.println("    all: dump all activities");
12312                pw.println("    top: dump the top activity");
12313                pw.println("    write: write all pending state to storage");
12314                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12315                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12316                pw.println("    a partial substring in a component name, a");
12317                pw.println("    hex object identifier.");
12318                pw.println("  -a: include all available server state.");
12319                pw.println("  -c: include client state.");
12320                return;
12321            } else {
12322                pw.println("Unknown argument: " + opt + "; use -h for help");
12323            }
12324        }
12325
12326        long origId = Binder.clearCallingIdentity();
12327        boolean more = false;
12328        // Is the caller requesting to dump a particular piece of data?
12329        if (opti < args.length) {
12330            String cmd = args[opti];
12331            opti++;
12332            if ("activities".equals(cmd) || "a".equals(cmd)) {
12333                synchronized (this) {
12334                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12335                }
12336            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12337                synchronized (this) {
12338                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12339                }
12340            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12341                String[] newArgs;
12342                String name;
12343                if (opti >= args.length) {
12344                    name = null;
12345                    newArgs = EMPTY_STRING_ARRAY;
12346                } else {
12347                    name = args[opti];
12348                    opti++;
12349                    newArgs = new String[args.length - opti];
12350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12351                            args.length - opti);
12352                }
12353                synchronized (this) {
12354                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12355                }
12356            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12357                String[] newArgs;
12358                String name;
12359                if (opti >= args.length) {
12360                    name = null;
12361                    newArgs = EMPTY_STRING_ARRAY;
12362                } else {
12363                    name = args[opti];
12364                    opti++;
12365                    newArgs = new String[args.length - opti];
12366                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12367                            args.length - opti);
12368                }
12369                synchronized (this) {
12370                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12371                }
12372            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12373                String[] newArgs;
12374                String name;
12375                if (opti >= args.length) {
12376                    name = null;
12377                    newArgs = EMPTY_STRING_ARRAY;
12378                } else {
12379                    name = args[opti];
12380                    opti++;
12381                    newArgs = new String[args.length - opti];
12382                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12383                            args.length - opti);
12384                }
12385                synchronized (this) {
12386                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12387                }
12388            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12389                synchronized (this) {
12390                    dumpOomLocked(fd, pw, args, opti, true);
12391                }
12392            } else if ("provider".equals(cmd)) {
12393                String[] newArgs;
12394                String name;
12395                if (opti >= args.length) {
12396                    name = null;
12397                    newArgs = EMPTY_STRING_ARRAY;
12398                } else {
12399                    name = args[opti];
12400                    opti++;
12401                    newArgs = new String[args.length - opti];
12402                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12403                }
12404                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12405                    pw.println("No providers match: " + name);
12406                    pw.println("Use -h for help.");
12407                }
12408            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12409                synchronized (this) {
12410                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12411                }
12412            } else if ("service".equals(cmd)) {
12413                String[] newArgs;
12414                String name;
12415                if (opti >= args.length) {
12416                    name = null;
12417                    newArgs = EMPTY_STRING_ARRAY;
12418                } else {
12419                    name = args[opti];
12420                    opti++;
12421                    newArgs = new String[args.length - opti];
12422                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12423                            args.length - opti);
12424                }
12425                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12426                    pw.println("No services match: " + name);
12427                    pw.println("Use -h for help.");
12428                }
12429            } else if ("package".equals(cmd)) {
12430                String[] newArgs;
12431                if (opti >= args.length) {
12432                    pw.println("package: no package name specified");
12433                    pw.println("Use -h for help.");
12434                } else {
12435                    dumpPackage = args[opti];
12436                    opti++;
12437                    newArgs = new String[args.length - opti];
12438                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12439                            args.length - opti);
12440                    args = newArgs;
12441                    opti = 0;
12442                    more = true;
12443                }
12444            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12445                synchronized (this) {
12446                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12447                }
12448            } else if ("write".equals(cmd)) {
12449                mTaskPersister.flush();
12450                pw.println("All tasks persisted.");
12451                return;
12452            } else {
12453                // Dumping a single activity?
12454                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12455                    pw.println("Bad activity command, or no activities match: " + cmd);
12456                    pw.println("Use -h for help.");
12457                }
12458            }
12459            if (!more) {
12460                Binder.restoreCallingIdentity(origId);
12461                return;
12462            }
12463        }
12464
12465        // No piece of data specified, dump everything.
12466        synchronized (this) {
12467            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12468            pw.println();
12469            if (dumpAll) {
12470                pw.println("-------------------------------------------------------------------------------");
12471            }
12472            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12473            pw.println();
12474            if (dumpAll) {
12475                pw.println("-------------------------------------------------------------------------------");
12476            }
12477            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12478            pw.println();
12479            if (dumpAll) {
12480                pw.println("-------------------------------------------------------------------------------");
12481            }
12482            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12483            pw.println();
12484            if (dumpAll) {
12485                pw.println("-------------------------------------------------------------------------------");
12486            }
12487            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12488            pw.println();
12489            if (dumpAll) {
12490                pw.println("-------------------------------------------------------------------------------");
12491            }
12492            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12493            pw.println();
12494            if (dumpAll) {
12495                pw.println("-------------------------------------------------------------------------------");
12496            }
12497            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12498        }
12499        Binder.restoreCallingIdentity(origId);
12500    }
12501
12502    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12503            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12504        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12505
12506        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12507                dumpPackage);
12508        boolean needSep = printedAnything;
12509
12510        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12511                dumpPackage, needSep, "  mFocusedActivity: ");
12512        if (printed) {
12513            printedAnything = true;
12514            needSep = false;
12515        }
12516
12517        if (dumpPackage == null) {
12518            if (needSep) {
12519                pw.println();
12520            }
12521            needSep = true;
12522            printedAnything = true;
12523            mStackSupervisor.dump(pw, "  ");
12524        }
12525
12526        if (!printedAnything) {
12527            pw.println("  (nothing)");
12528        }
12529    }
12530
12531    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12532            int opti, boolean dumpAll, String dumpPackage) {
12533        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12534
12535        boolean printedAnything = false;
12536
12537        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12538            boolean printedHeader = false;
12539
12540            final int N = mRecentTasks.size();
12541            for (int i=0; i<N; i++) {
12542                TaskRecord tr = mRecentTasks.get(i);
12543                if (dumpPackage != null) {
12544                    if (tr.realActivity == null ||
12545                            !dumpPackage.equals(tr.realActivity)) {
12546                        continue;
12547                    }
12548                }
12549                if (!printedHeader) {
12550                    pw.println("  Recent tasks:");
12551                    printedHeader = true;
12552                    printedAnything = true;
12553                }
12554                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12555                        pw.println(tr);
12556                if (dumpAll) {
12557                    mRecentTasks.get(i).dump(pw, "    ");
12558                }
12559            }
12560        }
12561
12562        if (!printedAnything) {
12563            pw.println("  (nothing)");
12564        }
12565    }
12566
12567    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12568            int opti, boolean dumpAll, String dumpPackage) {
12569        boolean needSep = false;
12570        boolean printedAnything = false;
12571        int numPers = 0;
12572
12573        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12574
12575        if (dumpAll) {
12576            final int NP = mProcessNames.getMap().size();
12577            for (int ip=0; ip<NP; ip++) {
12578                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12579                final int NA = procs.size();
12580                for (int ia=0; ia<NA; ia++) {
12581                    ProcessRecord r = procs.valueAt(ia);
12582                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12583                        continue;
12584                    }
12585                    if (!needSep) {
12586                        pw.println("  All known processes:");
12587                        needSep = true;
12588                        printedAnything = true;
12589                    }
12590                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12591                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12592                        pw.print(" "); pw.println(r);
12593                    r.dump(pw, "    ");
12594                    if (r.persistent) {
12595                        numPers++;
12596                    }
12597                }
12598            }
12599        }
12600
12601        if (mIsolatedProcesses.size() > 0) {
12602            boolean printed = false;
12603            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12604                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12605                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12606                    continue;
12607                }
12608                if (!printed) {
12609                    if (needSep) {
12610                        pw.println();
12611                    }
12612                    pw.println("  Isolated process list (sorted by uid):");
12613                    printedAnything = true;
12614                    printed = true;
12615                    needSep = true;
12616                }
12617                pw.println(String.format("%sIsolated #%2d: %s",
12618                        "    ", i, r.toString()));
12619            }
12620        }
12621
12622        if (mLruProcesses.size() > 0) {
12623            if (needSep) {
12624                pw.println();
12625            }
12626            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12627                    pw.print(" total, non-act at ");
12628                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12629                    pw.print(", non-svc at ");
12630                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12631                    pw.println("):");
12632            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12633            needSep = true;
12634            printedAnything = true;
12635        }
12636
12637        if (dumpAll || dumpPackage != null) {
12638            synchronized (mPidsSelfLocked) {
12639                boolean printed = false;
12640                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12641                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12642                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12643                        continue;
12644                    }
12645                    if (!printed) {
12646                        if (needSep) pw.println();
12647                        needSep = true;
12648                        pw.println("  PID mappings:");
12649                        printed = true;
12650                        printedAnything = true;
12651                    }
12652                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12653                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12654                }
12655            }
12656        }
12657
12658        if (mForegroundProcesses.size() > 0) {
12659            synchronized (mPidsSelfLocked) {
12660                boolean printed = false;
12661                for (int i=0; i<mForegroundProcesses.size(); i++) {
12662                    ProcessRecord r = mPidsSelfLocked.get(
12663                            mForegroundProcesses.valueAt(i).pid);
12664                    if (dumpPackage != null && (r == null
12665                            || !r.pkgList.containsKey(dumpPackage))) {
12666                        continue;
12667                    }
12668                    if (!printed) {
12669                        if (needSep) pw.println();
12670                        needSep = true;
12671                        pw.println("  Foreground Processes:");
12672                        printed = true;
12673                        printedAnything = true;
12674                    }
12675                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12676                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12677                }
12678            }
12679        }
12680
12681        if (mPersistentStartingProcesses.size() > 0) {
12682            if (needSep) pw.println();
12683            needSep = true;
12684            printedAnything = true;
12685            pw.println("  Persisent processes that are starting:");
12686            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12687                    "Starting Norm", "Restarting PERS", dumpPackage);
12688        }
12689
12690        if (mRemovedProcesses.size() > 0) {
12691            if (needSep) pw.println();
12692            needSep = true;
12693            printedAnything = true;
12694            pw.println("  Processes that are being removed:");
12695            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12696                    "Removed Norm", "Removed PERS", dumpPackage);
12697        }
12698
12699        if (mProcessesOnHold.size() > 0) {
12700            if (needSep) pw.println();
12701            needSep = true;
12702            printedAnything = true;
12703            pw.println("  Processes that are on old until the system is ready:");
12704            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12705                    "OnHold Norm", "OnHold PERS", dumpPackage);
12706        }
12707
12708        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12709
12710        if (mProcessCrashTimes.getMap().size() > 0) {
12711            boolean printed = false;
12712            long now = SystemClock.uptimeMillis();
12713            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12714            final int NP = pmap.size();
12715            for (int ip=0; ip<NP; ip++) {
12716                String pname = pmap.keyAt(ip);
12717                SparseArray<Long> uids = pmap.valueAt(ip);
12718                final int N = uids.size();
12719                for (int i=0; i<N; i++) {
12720                    int puid = uids.keyAt(i);
12721                    ProcessRecord r = mProcessNames.get(pname, puid);
12722                    if (dumpPackage != null && (r == null
12723                            || !r.pkgList.containsKey(dumpPackage))) {
12724                        continue;
12725                    }
12726                    if (!printed) {
12727                        if (needSep) pw.println();
12728                        needSep = true;
12729                        pw.println("  Time since processes crashed:");
12730                        printed = true;
12731                        printedAnything = true;
12732                    }
12733                    pw.print("    Process "); pw.print(pname);
12734                            pw.print(" uid "); pw.print(puid);
12735                            pw.print(": last crashed ");
12736                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12737                            pw.println(" ago");
12738                }
12739            }
12740        }
12741
12742        if (mBadProcesses.getMap().size() > 0) {
12743            boolean printed = false;
12744            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12745            final int NP = pmap.size();
12746            for (int ip=0; ip<NP; ip++) {
12747                String pname = pmap.keyAt(ip);
12748                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12749                final int N = uids.size();
12750                for (int i=0; i<N; i++) {
12751                    int puid = uids.keyAt(i);
12752                    ProcessRecord r = mProcessNames.get(pname, puid);
12753                    if (dumpPackage != null && (r == null
12754                            || !r.pkgList.containsKey(dumpPackage))) {
12755                        continue;
12756                    }
12757                    if (!printed) {
12758                        if (needSep) pw.println();
12759                        needSep = true;
12760                        pw.println("  Bad processes:");
12761                        printedAnything = true;
12762                    }
12763                    BadProcessInfo info = uids.valueAt(i);
12764                    pw.print("    Bad process "); pw.print(pname);
12765                            pw.print(" uid "); pw.print(puid);
12766                            pw.print(": crashed at time "); pw.println(info.time);
12767                    if (info.shortMsg != null) {
12768                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12769                    }
12770                    if (info.longMsg != null) {
12771                        pw.print("      Long msg: "); pw.println(info.longMsg);
12772                    }
12773                    if (info.stack != null) {
12774                        pw.println("      Stack:");
12775                        int lastPos = 0;
12776                        for (int pos=0; pos<info.stack.length(); pos++) {
12777                            if (info.stack.charAt(pos) == '\n') {
12778                                pw.print("        ");
12779                                pw.write(info.stack, lastPos, pos-lastPos);
12780                                pw.println();
12781                                lastPos = pos+1;
12782                            }
12783                        }
12784                        if (lastPos < info.stack.length()) {
12785                            pw.print("        ");
12786                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12787                            pw.println();
12788                        }
12789                    }
12790                }
12791            }
12792        }
12793
12794        if (dumpPackage == null) {
12795            pw.println();
12796            needSep = false;
12797            pw.println("  mStartedUsers:");
12798            for (int i=0; i<mStartedUsers.size(); i++) {
12799                UserStartedState uss = mStartedUsers.valueAt(i);
12800                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12801                        pw.print(": "); uss.dump("", pw);
12802            }
12803            pw.print("  mStartedUserArray: [");
12804            for (int i=0; i<mStartedUserArray.length; i++) {
12805                if (i > 0) pw.print(", ");
12806                pw.print(mStartedUserArray[i]);
12807            }
12808            pw.println("]");
12809            pw.print("  mUserLru: [");
12810            for (int i=0; i<mUserLru.size(); i++) {
12811                if (i > 0) pw.print(", ");
12812                pw.print(mUserLru.get(i));
12813            }
12814            pw.println("]");
12815            if (dumpAll) {
12816                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12817            }
12818            synchronized (mUserProfileGroupIdsSelfLocked) {
12819                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12820                    pw.println("  mUserProfileGroupIds:");
12821                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12822                        pw.print("    User #");
12823                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12824                        pw.print(" -> profile #");
12825                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12826                    }
12827                }
12828            }
12829        }
12830        if (mHomeProcess != null && (dumpPackage == null
12831                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12832            if (needSep) {
12833                pw.println();
12834                needSep = false;
12835            }
12836            pw.println("  mHomeProcess: " + mHomeProcess);
12837        }
12838        if (mPreviousProcess != null && (dumpPackage == null
12839                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12840            if (needSep) {
12841                pw.println();
12842                needSep = false;
12843            }
12844            pw.println("  mPreviousProcess: " + mPreviousProcess);
12845        }
12846        if (dumpAll) {
12847            StringBuilder sb = new StringBuilder(128);
12848            sb.append("  mPreviousProcessVisibleTime: ");
12849            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12850            pw.println(sb);
12851        }
12852        if (mHeavyWeightProcess != null && (dumpPackage == null
12853                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12854            if (needSep) {
12855                pw.println();
12856                needSep = false;
12857            }
12858            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12859        }
12860        if (dumpPackage == null) {
12861            pw.println("  mConfiguration: " + mConfiguration);
12862        }
12863        if (dumpAll) {
12864            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12865            if (mCompatModePackages.getPackages().size() > 0) {
12866                boolean printed = false;
12867                for (Map.Entry<String, Integer> entry
12868                        : mCompatModePackages.getPackages().entrySet()) {
12869                    String pkg = entry.getKey();
12870                    int mode = entry.getValue();
12871                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12872                        continue;
12873                    }
12874                    if (!printed) {
12875                        pw.println("  mScreenCompatPackages:");
12876                        printed = true;
12877                    }
12878                    pw.print("    "); pw.print(pkg); pw.print(": ");
12879                            pw.print(mode); pw.println();
12880                }
12881            }
12882        }
12883        if (dumpPackage == null) {
12884            pw.println("  mWakefulness="
12885                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12886            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12887                    + lockScreenShownToString());
12888            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12889        }
12890        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12891                || mOrigWaitForDebugger) {
12892            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12893                    || dumpPackage.equals(mOrigDebugApp)) {
12894                if (needSep) {
12895                    pw.println();
12896                    needSep = false;
12897                }
12898                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12899                        + " mDebugTransient=" + mDebugTransient
12900                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12901            }
12902        }
12903        if (mOpenGlTraceApp != null) {
12904            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12905                if (needSep) {
12906                    pw.println();
12907                    needSep = false;
12908                }
12909                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12910            }
12911        }
12912        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12913                || mProfileFd != null) {
12914            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12915                if (needSep) {
12916                    pw.println();
12917                    needSep = false;
12918                }
12919                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12920                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12921                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12922                        + mAutoStopProfiler);
12923                pw.println("  mProfileType=" + mProfileType);
12924            }
12925        }
12926        if (dumpPackage == null) {
12927            if (mAlwaysFinishActivities || mController != null) {
12928                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12929                        + " mController=" + mController);
12930            }
12931            if (dumpAll) {
12932                pw.println("  Total persistent processes: " + numPers);
12933                pw.println("  mProcessesReady=" + mProcessesReady
12934                        + " mSystemReady=" + mSystemReady
12935                        + " mBooted=" + mBooted
12936                        + " mFactoryTest=" + mFactoryTest);
12937                pw.println("  mBooting=" + mBooting
12938                        + " mCallFinishBooting=" + mCallFinishBooting
12939                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12940                pw.print("  mLastPowerCheckRealtime=");
12941                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12942                        pw.println("");
12943                pw.print("  mLastPowerCheckUptime=");
12944                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12945                        pw.println("");
12946                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12947                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12948                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12949                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12950                        + " (" + mLruProcesses.size() + " total)"
12951                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12952                        + " mNumServiceProcs=" + mNumServiceProcs
12953                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12954                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12955                        + " mLastMemoryLevel" + mLastMemoryLevel
12956                        + " mLastNumProcesses" + mLastNumProcesses);
12957                long now = SystemClock.uptimeMillis();
12958                pw.print("  mLastIdleTime=");
12959                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12960                        pw.print(" mLowRamSinceLastIdle=");
12961                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12962                        pw.println();
12963            }
12964        }
12965
12966        if (!printedAnything) {
12967            pw.println("  (nothing)");
12968        }
12969    }
12970
12971    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12972            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12973        if (mProcessesToGc.size() > 0) {
12974            boolean printed = false;
12975            long now = SystemClock.uptimeMillis();
12976            for (int i=0; i<mProcessesToGc.size(); i++) {
12977                ProcessRecord proc = mProcessesToGc.get(i);
12978                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12979                    continue;
12980                }
12981                if (!printed) {
12982                    if (needSep) pw.println();
12983                    needSep = true;
12984                    pw.println("  Processes that are waiting to GC:");
12985                    printed = true;
12986                }
12987                pw.print("    Process "); pw.println(proc);
12988                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12989                        pw.print(", last gced=");
12990                        pw.print(now-proc.lastRequestedGc);
12991                        pw.print(" ms ago, last lowMem=");
12992                        pw.print(now-proc.lastLowMemory);
12993                        pw.println(" ms ago");
12994
12995            }
12996        }
12997        return needSep;
12998    }
12999
13000    void printOomLevel(PrintWriter pw, String name, int adj) {
13001        pw.print("    ");
13002        if (adj >= 0) {
13003            pw.print(' ');
13004            if (adj < 10) pw.print(' ');
13005        } else {
13006            if (adj > -10) pw.print(' ');
13007        }
13008        pw.print(adj);
13009        pw.print(": ");
13010        pw.print(name);
13011        pw.print(" (");
13012        pw.print(mProcessList.getMemLevel(adj)/1024);
13013        pw.println(" kB)");
13014    }
13015
13016    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13017            int opti, boolean dumpAll) {
13018        boolean needSep = false;
13019
13020        if (mLruProcesses.size() > 0) {
13021            if (needSep) pw.println();
13022            needSep = true;
13023            pw.println("  OOM levels:");
13024            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13025            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13026            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13027            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13028            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13029            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13030            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13031            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13032            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13033            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13034            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13035            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13036            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13037            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13038
13039            if (needSep) pw.println();
13040            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13041                    pw.print(" total, non-act at ");
13042                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13043                    pw.print(", non-svc at ");
13044                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13045                    pw.println("):");
13046            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13047            needSep = true;
13048        }
13049
13050        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13051
13052        pw.println();
13053        pw.println("  mHomeProcess: " + mHomeProcess);
13054        pw.println("  mPreviousProcess: " + mPreviousProcess);
13055        if (mHeavyWeightProcess != null) {
13056            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13057        }
13058
13059        return true;
13060    }
13061
13062    /**
13063     * There are three ways to call this:
13064     *  - no provider specified: dump all the providers
13065     *  - a flattened component name that matched an existing provider was specified as the
13066     *    first arg: dump that one provider
13067     *  - the first arg isn't the flattened component name of an existing provider:
13068     *    dump all providers whose component contains the first arg as a substring
13069     */
13070    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13071            int opti, boolean dumpAll) {
13072        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13073    }
13074
13075    static class ItemMatcher {
13076        ArrayList<ComponentName> components;
13077        ArrayList<String> strings;
13078        ArrayList<Integer> objects;
13079        boolean all;
13080
13081        ItemMatcher() {
13082            all = true;
13083        }
13084
13085        void build(String name) {
13086            ComponentName componentName = ComponentName.unflattenFromString(name);
13087            if (componentName != null) {
13088                if (components == null) {
13089                    components = new ArrayList<ComponentName>();
13090                }
13091                components.add(componentName);
13092                all = false;
13093            } else {
13094                int objectId = 0;
13095                // Not a '/' separated full component name; maybe an object ID?
13096                try {
13097                    objectId = Integer.parseInt(name, 16);
13098                    if (objects == null) {
13099                        objects = new ArrayList<Integer>();
13100                    }
13101                    objects.add(objectId);
13102                    all = false;
13103                } catch (RuntimeException e) {
13104                    // Not an integer; just do string match.
13105                    if (strings == null) {
13106                        strings = new ArrayList<String>();
13107                    }
13108                    strings.add(name);
13109                    all = false;
13110                }
13111            }
13112        }
13113
13114        int build(String[] args, int opti) {
13115            for (; opti<args.length; opti++) {
13116                String name = args[opti];
13117                if ("--".equals(name)) {
13118                    return opti+1;
13119                }
13120                build(name);
13121            }
13122            return opti;
13123        }
13124
13125        boolean match(Object object, ComponentName comp) {
13126            if (all) {
13127                return true;
13128            }
13129            if (components != null) {
13130                for (int i=0; i<components.size(); i++) {
13131                    if (components.get(i).equals(comp)) {
13132                        return true;
13133                    }
13134                }
13135            }
13136            if (objects != null) {
13137                for (int i=0; i<objects.size(); i++) {
13138                    if (System.identityHashCode(object) == objects.get(i)) {
13139                        return true;
13140                    }
13141                }
13142            }
13143            if (strings != null) {
13144                String flat = comp.flattenToString();
13145                for (int i=0; i<strings.size(); i++) {
13146                    if (flat.contains(strings.get(i))) {
13147                        return true;
13148                    }
13149                }
13150            }
13151            return false;
13152        }
13153    }
13154
13155    /**
13156     * There are three things that cmd can be:
13157     *  - a flattened component name that matches an existing activity
13158     *  - the cmd arg isn't the flattened component name of an existing activity:
13159     *    dump all activity whose component contains the cmd as a substring
13160     *  - A hex number of the ActivityRecord object instance.
13161     */
13162    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13163            int opti, boolean dumpAll) {
13164        ArrayList<ActivityRecord> activities;
13165
13166        synchronized (this) {
13167            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13168        }
13169
13170        if (activities.size() <= 0) {
13171            return false;
13172        }
13173
13174        String[] newArgs = new String[args.length - opti];
13175        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13176
13177        TaskRecord lastTask = null;
13178        boolean needSep = false;
13179        for (int i=activities.size()-1; i>=0; i--) {
13180            ActivityRecord r = activities.get(i);
13181            if (needSep) {
13182                pw.println();
13183            }
13184            needSep = true;
13185            synchronized (this) {
13186                if (lastTask != r.task) {
13187                    lastTask = r.task;
13188                    pw.print("TASK "); pw.print(lastTask.affinity);
13189                            pw.print(" id="); pw.println(lastTask.taskId);
13190                    if (dumpAll) {
13191                        lastTask.dump(pw, "  ");
13192                    }
13193                }
13194            }
13195            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13196        }
13197        return true;
13198    }
13199
13200    /**
13201     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13202     * there is a thread associated with the activity.
13203     */
13204    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13205            final ActivityRecord r, String[] args, boolean dumpAll) {
13206        String innerPrefix = prefix + "  ";
13207        synchronized (this) {
13208            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13209                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13210                    pw.print(" pid=");
13211                    if (r.app != null) pw.println(r.app.pid);
13212                    else pw.println("(not running)");
13213            if (dumpAll) {
13214                r.dump(pw, innerPrefix);
13215            }
13216        }
13217        if (r.app != null && r.app.thread != null) {
13218            // flush anything that is already in the PrintWriter since the thread is going
13219            // to write to the file descriptor directly
13220            pw.flush();
13221            try {
13222                TransferPipe tp = new TransferPipe();
13223                try {
13224                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13225                            r.appToken, innerPrefix, args);
13226                    tp.go(fd);
13227                } finally {
13228                    tp.kill();
13229                }
13230            } catch (IOException e) {
13231                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13232            } catch (RemoteException e) {
13233                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13234            }
13235        }
13236    }
13237
13238    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13239            int opti, boolean dumpAll, String dumpPackage) {
13240        boolean needSep = false;
13241        boolean onlyHistory = false;
13242        boolean printedAnything = false;
13243
13244        if ("history".equals(dumpPackage)) {
13245            if (opti < args.length && "-s".equals(args[opti])) {
13246                dumpAll = false;
13247            }
13248            onlyHistory = true;
13249            dumpPackage = null;
13250        }
13251
13252        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13253        if (!onlyHistory && dumpAll) {
13254            if (mRegisteredReceivers.size() > 0) {
13255                boolean printed = false;
13256                Iterator it = mRegisteredReceivers.values().iterator();
13257                while (it.hasNext()) {
13258                    ReceiverList r = (ReceiverList)it.next();
13259                    if (dumpPackage != null && (r.app == null ||
13260                            !dumpPackage.equals(r.app.info.packageName))) {
13261                        continue;
13262                    }
13263                    if (!printed) {
13264                        pw.println("  Registered Receivers:");
13265                        needSep = true;
13266                        printed = true;
13267                        printedAnything = true;
13268                    }
13269                    pw.print("  * "); pw.println(r);
13270                    r.dump(pw, "    ");
13271                }
13272            }
13273
13274            if (mReceiverResolver.dump(pw, needSep ?
13275                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13276                    "    ", dumpPackage, false, false)) {
13277                needSep = true;
13278                printedAnything = true;
13279            }
13280        }
13281
13282        for (BroadcastQueue q : mBroadcastQueues) {
13283            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13284            printedAnything |= needSep;
13285        }
13286
13287        needSep = true;
13288
13289        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13290            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13291                if (needSep) {
13292                    pw.println();
13293                }
13294                needSep = true;
13295                printedAnything = true;
13296                pw.print("  Sticky broadcasts for user ");
13297                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13298                StringBuilder sb = new StringBuilder(128);
13299                for (Map.Entry<String, ArrayList<Intent>> ent
13300                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13301                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13302                    if (dumpAll) {
13303                        pw.println(":");
13304                        ArrayList<Intent> intents = ent.getValue();
13305                        final int N = intents.size();
13306                        for (int i=0; i<N; i++) {
13307                            sb.setLength(0);
13308                            sb.append("    Intent: ");
13309                            intents.get(i).toShortString(sb, false, true, false, false);
13310                            pw.println(sb.toString());
13311                            Bundle bundle = intents.get(i).getExtras();
13312                            if (bundle != null) {
13313                                pw.print("      ");
13314                                pw.println(bundle.toString());
13315                            }
13316                        }
13317                    } else {
13318                        pw.println("");
13319                    }
13320                }
13321            }
13322        }
13323
13324        if (!onlyHistory && dumpAll) {
13325            pw.println();
13326            for (BroadcastQueue queue : mBroadcastQueues) {
13327                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13328                        + queue.mBroadcastsScheduled);
13329            }
13330            pw.println("  mHandler:");
13331            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13332            needSep = true;
13333            printedAnything = true;
13334        }
13335
13336        if (!printedAnything) {
13337            pw.println("  (nothing)");
13338        }
13339    }
13340
13341    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13342            int opti, boolean dumpAll, String dumpPackage) {
13343        boolean needSep;
13344        boolean printedAnything = false;
13345
13346        ItemMatcher matcher = new ItemMatcher();
13347        matcher.build(args, opti);
13348
13349        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13350
13351        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13352        printedAnything |= needSep;
13353
13354        if (mLaunchingProviders.size() > 0) {
13355            boolean printed = false;
13356            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13357                ContentProviderRecord r = mLaunchingProviders.get(i);
13358                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13359                    continue;
13360                }
13361                if (!printed) {
13362                    if (needSep) pw.println();
13363                    needSep = true;
13364                    pw.println("  Launching content providers:");
13365                    printed = true;
13366                    printedAnything = true;
13367                }
13368                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13369                        pw.println(r);
13370            }
13371        }
13372
13373        if (mGrantedUriPermissions.size() > 0) {
13374            boolean printed = false;
13375            int dumpUid = -2;
13376            if (dumpPackage != null) {
13377                try {
13378                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13379                } catch (NameNotFoundException e) {
13380                    dumpUid = -1;
13381                }
13382            }
13383            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13384                int uid = mGrantedUriPermissions.keyAt(i);
13385                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13386                    continue;
13387                }
13388                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13389                if (!printed) {
13390                    if (needSep) pw.println();
13391                    needSep = true;
13392                    pw.println("  Granted Uri Permissions:");
13393                    printed = true;
13394                    printedAnything = true;
13395                }
13396                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13397                for (UriPermission perm : perms.values()) {
13398                    pw.print("    "); pw.println(perm);
13399                    if (dumpAll) {
13400                        perm.dump(pw, "      ");
13401                    }
13402                }
13403            }
13404        }
13405
13406        if (!printedAnything) {
13407            pw.println("  (nothing)");
13408        }
13409    }
13410
13411    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13412            int opti, boolean dumpAll, String dumpPackage) {
13413        boolean printed = false;
13414
13415        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13416
13417        if (mIntentSenderRecords.size() > 0) {
13418            Iterator<WeakReference<PendingIntentRecord>> it
13419                    = mIntentSenderRecords.values().iterator();
13420            while (it.hasNext()) {
13421                WeakReference<PendingIntentRecord> ref = it.next();
13422                PendingIntentRecord rec = ref != null ? ref.get(): null;
13423                if (dumpPackage != null && (rec == null
13424                        || !dumpPackage.equals(rec.key.packageName))) {
13425                    continue;
13426                }
13427                printed = true;
13428                if (rec != null) {
13429                    pw.print("  * "); pw.println(rec);
13430                    if (dumpAll) {
13431                        rec.dump(pw, "    ");
13432                    }
13433                } else {
13434                    pw.print("  * "); pw.println(ref);
13435                }
13436            }
13437        }
13438
13439        if (!printed) {
13440            pw.println("  (nothing)");
13441        }
13442    }
13443
13444    private static final int dumpProcessList(PrintWriter pw,
13445            ActivityManagerService service, List list,
13446            String prefix, String normalLabel, String persistentLabel,
13447            String dumpPackage) {
13448        int numPers = 0;
13449        final int N = list.size()-1;
13450        for (int i=N; i>=0; i--) {
13451            ProcessRecord r = (ProcessRecord)list.get(i);
13452            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13453                continue;
13454            }
13455            pw.println(String.format("%s%s #%2d: %s",
13456                    prefix, (r.persistent ? persistentLabel : normalLabel),
13457                    i, r.toString()));
13458            if (r.persistent) {
13459                numPers++;
13460            }
13461        }
13462        return numPers;
13463    }
13464
13465    private static final boolean dumpProcessOomList(PrintWriter pw,
13466            ActivityManagerService service, List<ProcessRecord> origList,
13467            String prefix, String normalLabel, String persistentLabel,
13468            boolean inclDetails, String dumpPackage) {
13469
13470        ArrayList<Pair<ProcessRecord, Integer>> list
13471                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13472        for (int i=0; i<origList.size(); i++) {
13473            ProcessRecord r = origList.get(i);
13474            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13475                continue;
13476            }
13477            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13478        }
13479
13480        if (list.size() <= 0) {
13481            return false;
13482        }
13483
13484        Comparator<Pair<ProcessRecord, Integer>> comparator
13485                = new Comparator<Pair<ProcessRecord, Integer>>() {
13486            @Override
13487            public int compare(Pair<ProcessRecord, Integer> object1,
13488                    Pair<ProcessRecord, Integer> object2) {
13489                if (object1.first.setAdj != object2.first.setAdj) {
13490                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13491                }
13492                if (object1.second.intValue() != object2.second.intValue()) {
13493                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13494                }
13495                return 0;
13496            }
13497        };
13498
13499        Collections.sort(list, comparator);
13500
13501        final long curRealtime = SystemClock.elapsedRealtime();
13502        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13503        final long curUptime = SystemClock.uptimeMillis();
13504        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13505
13506        for (int i=list.size()-1; i>=0; i--) {
13507            ProcessRecord r = list.get(i).first;
13508            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13509            char schedGroup;
13510            switch (r.setSchedGroup) {
13511                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13512                    schedGroup = 'B';
13513                    break;
13514                case Process.THREAD_GROUP_DEFAULT:
13515                    schedGroup = 'F';
13516                    break;
13517                default:
13518                    schedGroup = '?';
13519                    break;
13520            }
13521            char foreground;
13522            if (r.foregroundActivities) {
13523                foreground = 'A';
13524            } else if (r.foregroundServices) {
13525                foreground = 'S';
13526            } else {
13527                foreground = ' ';
13528            }
13529            String procState = ProcessList.makeProcStateString(r.curProcState);
13530            pw.print(prefix);
13531            pw.print(r.persistent ? persistentLabel : normalLabel);
13532            pw.print(" #");
13533            int num = (origList.size()-1)-list.get(i).second;
13534            if (num < 10) pw.print(' ');
13535            pw.print(num);
13536            pw.print(": ");
13537            pw.print(oomAdj);
13538            pw.print(' ');
13539            pw.print(schedGroup);
13540            pw.print('/');
13541            pw.print(foreground);
13542            pw.print('/');
13543            pw.print(procState);
13544            pw.print(" trm:");
13545            if (r.trimMemoryLevel < 10) pw.print(' ');
13546            pw.print(r.trimMemoryLevel);
13547            pw.print(' ');
13548            pw.print(r.toShortString());
13549            pw.print(" (");
13550            pw.print(r.adjType);
13551            pw.println(')');
13552            if (r.adjSource != null || r.adjTarget != null) {
13553                pw.print(prefix);
13554                pw.print("    ");
13555                if (r.adjTarget instanceof ComponentName) {
13556                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13557                } else if (r.adjTarget != null) {
13558                    pw.print(r.adjTarget.toString());
13559                } else {
13560                    pw.print("{null}");
13561                }
13562                pw.print("<=");
13563                if (r.adjSource instanceof ProcessRecord) {
13564                    pw.print("Proc{");
13565                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13566                    pw.println("}");
13567                } else if (r.adjSource != null) {
13568                    pw.println(r.adjSource.toString());
13569                } else {
13570                    pw.println("{null}");
13571                }
13572            }
13573            if (inclDetails) {
13574                pw.print(prefix);
13575                pw.print("    ");
13576                pw.print("oom: max="); pw.print(r.maxAdj);
13577                pw.print(" curRaw="); pw.print(r.curRawAdj);
13578                pw.print(" setRaw="); pw.print(r.setRawAdj);
13579                pw.print(" cur="); pw.print(r.curAdj);
13580                pw.print(" set="); pw.println(r.setAdj);
13581                pw.print(prefix);
13582                pw.print("    ");
13583                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13584                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13585                pw.print(" lastPss="); pw.print(r.lastPss);
13586                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13587                pw.print(prefix);
13588                pw.print("    ");
13589                pw.print("cached="); pw.print(r.cached);
13590                pw.print(" empty="); pw.print(r.empty);
13591                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13592
13593                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13594                    if (r.lastWakeTime != 0) {
13595                        long wtime;
13596                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13597                        synchronized (stats) {
13598                            wtime = stats.getProcessWakeTime(r.info.uid,
13599                                    r.pid, curRealtime);
13600                        }
13601                        long timeUsed = wtime - r.lastWakeTime;
13602                        pw.print(prefix);
13603                        pw.print("    ");
13604                        pw.print("keep awake over ");
13605                        TimeUtils.formatDuration(realtimeSince, pw);
13606                        pw.print(" used ");
13607                        TimeUtils.formatDuration(timeUsed, pw);
13608                        pw.print(" (");
13609                        pw.print((timeUsed*100)/realtimeSince);
13610                        pw.println("%)");
13611                    }
13612                    if (r.lastCpuTime != 0) {
13613                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13614                        pw.print(prefix);
13615                        pw.print("    ");
13616                        pw.print("run cpu over ");
13617                        TimeUtils.formatDuration(uptimeSince, pw);
13618                        pw.print(" used ");
13619                        TimeUtils.formatDuration(timeUsed, pw);
13620                        pw.print(" (");
13621                        pw.print((timeUsed*100)/uptimeSince);
13622                        pw.println("%)");
13623                    }
13624                }
13625            }
13626        }
13627        return true;
13628    }
13629
13630    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13631            String[] args) {
13632        ArrayList<ProcessRecord> procs;
13633        synchronized (this) {
13634            if (args != null && args.length > start
13635                    && args[start].charAt(0) != '-') {
13636                procs = new ArrayList<ProcessRecord>();
13637                int pid = -1;
13638                try {
13639                    pid = Integer.parseInt(args[start]);
13640                } catch (NumberFormatException e) {
13641                }
13642                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13643                    ProcessRecord proc = mLruProcesses.get(i);
13644                    if (proc.pid == pid) {
13645                        procs.add(proc);
13646                    } else if (allPkgs && proc.pkgList != null
13647                            && proc.pkgList.containsKey(args[start])) {
13648                        procs.add(proc);
13649                    } else if (proc.processName.equals(args[start])) {
13650                        procs.add(proc);
13651                    }
13652                }
13653                if (procs.size() <= 0) {
13654                    return null;
13655                }
13656            } else {
13657                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13658            }
13659        }
13660        return procs;
13661    }
13662
13663    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13664            PrintWriter pw, String[] args) {
13665        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13666        if (procs == null) {
13667            pw.println("No process found for: " + args[0]);
13668            return;
13669        }
13670
13671        long uptime = SystemClock.uptimeMillis();
13672        long realtime = SystemClock.elapsedRealtime();
13673        pw.println("Applications Graphics Acceleration Info:");
13674        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13675
13676        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13677            ProcessRecord r = procs.get(i);
13678            if (r.thread != null) {
13679                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13680                pw.flush();
13681                try {
13682                    TransferPipe tp = new TransferPipe();
13683                    try {
13684                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13685                        tp.go(fd);
13686                    } finally {
13687                        tp.kill();
13688                    }
13689                } catch (IOException e) {
13690                    pw.println("Failure while dumping the app: " + r);
13691                    pw.flush();
13692                } catch (RemoteException e) {
13693                    pw.println("Got a RemoteException while dumping the app " + r);
13694                    pw.flush();
13695                }
13696            }
13697        }
13698    }
13699
13700    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13701        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13702        if (procs == null) {
13703            pw.println("No process found for: " + args[0]);
13704            return;
13705        }
13706
13707        pw.println("Applications Database Info:");
13708
13709        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13710            ProcessRecord r = procs.get(i);
13711            if (r.thread != null) {
13712                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13713                pw.flush();
13714                try {
13715                    TransferPipe tp = new TransferPipe();
13716                    try {
13717                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13718                        tp.go(fd);
13719                    } finally {
13720                        tp.kill();
13721                    }
13722                } catch (IOException e) {
13723                    pw.println("Failure while dumping the app: " + r);
13724                    pw.flush();
13725                } catch (RemoteException e) {
13726                    pw.println("Got a RemoteException while dumping the app " + r);
13727                    pw.flush();
13728                }
13729            }
13730        }
13731    }
13732
13733    final static class MemItem {
13734        final boolean isProc;
13735        final String label;
13736        final String shortLabel;
13737        final long pss;
13738        final int id;
13739        final boolean hasActivities;
13740        ArrayList<MemItem> subitems;
13741
13742        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13743                boolean _hasActivities) {
13744            isProc = true;
13745            label = _label;
13746            shortLabel = _shortLabel;
13747            pss = _pss;
13748            id = _id;
13749            hasActivities = _hasActivities;
13750        }
13751
13752        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13753            isProc = false;
13754            label = _label;
13755            shortLabel = _shortLabel;
13756            pss = _pss;
13757            id = _id;
13758            hasActivities = false;
13759        }
13760    }
13761
13762    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13763            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13764        if (sort && !isCompact) {
13765            Collections.sort(items, new Comparator<MemItem>() {
13766                @Override
13767                public int compare(MemItem lhs, MemItem rhs) {
13768                    if (lhs.pss < rhs.pss) {
13769                        return 1;
13770                    } else if (lhs.pss > rhs.pss) {
13771                        return -1;
13772                    }
13773                    return 0;
13774                }
13775            });
13776        }
13777
13778        for (int i=0; i<items.size(); i++) {
13779            MemItem mi = items.get(i);
13780            if (!isCompact) {
13781                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13782            } else if (mi.isProc) {
13783                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13784                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13785                pw.println(mi.hasActivities ? ",a" : ",e");
13786            } else {
13787                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13788                pw.println(mi.pss);
13789            }
13790            if (mi.subitems != null) {
13791                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13792                        true, isCompact);
13793            }
13794        }
13795    }
13796
13797    // These are in KB.
13798    static final long[] DUMP_MEM_BUCKETS = new long[] {
13799        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13800        120*1024, 160*1024, 200*1024,
13801        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13802        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13803    };
13804
13805    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13806            boolean stackLike) {
13807        int start = label.lastIndexOf('.');
13808        if (start >= 0) start++;
13809        else start = 0;
13810        int end = label.length();
13811        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13812            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13813                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13814                out.append(bucket);
13815                out.append(stackLike ? "MB." : "MB ");
13816                out.append(label, start, end);
13817                return;
13818            }
13819        }
13820        out.append(memKB/1024);
13821        out.append(stackLike ? "MB." : "MB ");
13822        out.append(label, start, end);
13823    }
13824
13825    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13826            ProcessList.NATIVE_ADJ,
13827            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13828            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13829            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13830            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13831            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13832            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13833    };
13834    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13835            "Native",
13836            "System", "Persistent", "Persistent Service", "Foreground",
13837            "Visible", "Perceptible",
13838            "Heavy Weight", "Backup",
13839            "A Services", "Home",
13840            "Previous", "B Services", "Cached"
13841    };
13842    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13843            "native",
13844            "sys", "pers", "persvc", "fore",
13845            "vis", "percept",
13846            "heavy", "backup",
13847            "servicea", "home",
13848            "prev", "serviceb", "cached"
13849    };
13850
13851    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13852            long realtime, boolean isCheckinRequest, boolean isCompact) {
13853        if (isCheckinRequest || isCompact) {
13854            // short checkin version
13855            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13856        } else {
13857            pw.println("Applications Memory Usage (kB):");
13858            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13859        }
13860    }
13861
13862    private static final int KSM_SHARED = 0;
13863    private static final int KSM_SHARING = 1;
13864    private static final int KSM_UNSHARED = 2;
13865    private static final int KSM_VOLATILE = 3;
13866
13867    private final long[] getKsmInfo() {
13868        long[] longOut = new long[4];
13869        final int[] SINGLE_LONG_FORMAT = new int[] {
13870            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13871        };
13872        long[] longTmp = new long[1];
13873        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13874                SINGLE_LONG_FORMAT, null, longTmp, null);
13875        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13876        longTmp[0] = 0;
13877        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13878                SINGLE_LONG_FORMAT, null, longTmp, null);
13879        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13880        longTmp[0] = 0;
13881        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13882                SINGLE_LONG_FORMAT, null, longTmp, null);
13883        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13884        longTmp[0] = 0;
13885        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13886                SINGLE_LONG_FORMAT, null, longTmp, null);
13887        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13888        return longOut;
13889    }
13890
13891    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13892            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13893        boolean dumpDetails = false;
13894        boolean dumpFullDetails = false;
13895        boolean dumpDalvik = false;
13896        boolean oomOnly = false;
13897        boolean isCompact = false;
13898        boolean localOnly = false;
13899        boolean packages = false;
13900
13901        int opti = 0;
13902        while (opti < args.length) {
13903            String opt = args[opti];
13904            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13905                break;
13906            }
13907            opti++;
13908            if ("-a".equals(opt)) {
13909                dumpDetails = true;
13910                dumpFullDetails = true;
13911                dumpDalvik = true;
13912            } else if ("-d".equals(opt)) {
13913                dumpDalvik = true;
13914            } else if ("-c".equals(opt)) {
13915                isCompact = true;
13916            } else if ("--oom".equals(opt)) {
13917                oomOnly = true;
13918            } else if ("--local".equals(opt)) {
13919                localOnly = true;
13920            } else if ("--package".equals(opt)) {
13921                packages = true;
13922            } else if ("-h".equals(opt)) {
13923                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13924                pw.println("  -a: include all available information for each process.");
13925                pw.println("  -d: include dalvik details when dumping process details.");
13926                pw.println("  -c: dump in a compact machine-parseable representation.");
13927                pw.println("  --oom: only show processes organized by oom adj.");
13928                pw.println("  --local: only collect details locally, don't call process.");
13929                pw.println("  --package: interpret process arg as package, dumping all");
13930                pw.println("             processes that have loaded that package.");
13931                pw.println("If [process] is specified it can be the name or ");
13932                pw.println("pid of a specific process to dump.");
13933                return;
13934            } else {
13935                pw.println("Unknown argument: " + opt + "; use -h for help");
13936            }
13937        }
13938
13939        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13940        long uptime = SystemClock.uptimeMillis();
13941        long realtime = SystemClock.elapsedRealtime();
13942        final long[] tmpLong = new long[1];
13943
13944        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13945        if (procs == null) {
13946            // No Java processes.  Maybe they want to print a native process.
13947            if (args != null && args.length > opti
13948                    && args[opti].charAt(0) != '-') {
13949                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13950                        = new ArrayList<ProcessCpuTracker.Stats>();
13951                updateCpuStatsNow();
13952                int findPid = -1;
13953                try {
13954                    findPid = Integer.parseInt(args[opti]);
13955                } catch (NumberFormatException e) {
13956                }
13957                synchronized (mProcessCpuTracker) {
13958                    final int N = mProcessCpuTracker.countStats();
13959                    for (int i=0; i<N; i++) {
13960                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13961                        if (st.pid == findPid || (st.baseName != null
13962                                && st.baseName.equals(args[opti]))) {
13963                            nativeProcs.add(st);
13964                        }
13965                    }
13966                }
13967                if (nativeProcs.size() > 0) {
13968                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13969                            isCompact);
13970                    Debug.MemoryInfo mi = null;
13971                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13972                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13973                        final int pid = r.pid;
13974                        if (!isCheckinRequest && dumpDetails) {
13975                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13976                        }
13977                        if (mi == null) {
13978                            mi = new Debug.MemoryInfo();
13979                        }
13980                        if (dumpDetails || (!brief && !oomOnly)) {
13981                            Debug.getMemoryInfo(pid, mi);
13982                        } else {
13983                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13984                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13985                        }
13986                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13987                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13988                        if (isCheckinRequest) {
13989                            pw.println();
13990                        }
13991                    }
13992                    return;
13993                }
13994            }
13995            pw.println("No process found for: " + args[opti]);
13996            return;
13997        }
13998
13999        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14000            dumpDetails = true;
14001        }
14002
14003        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14004
14005        String[] innerArgs = new String[args.length-opti];
14006        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14007
14008        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14009        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14010        long nativePss = 0;
14011        long dalvikPss = 0;
14012        long otherPss = 0;
14013        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14014
14015        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14016        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14017                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14018
14019        long totalPss = 0;
14020        long cachedPss = 0;
14021
14022        Debug.MemoryInfo mi = null;
14023        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14024            final ProcessRecord r = procs.get(i);
14025            final IApplicationThread thread;
14026            final int pid;
14027            final int oomAdj;
14028            final boolean hasActivities;
14029            synchronized (this) {
14030                thread = r.thread;
14031                pid = r.pid;
14032                oomAdj = r.getSetAdjWithServices();
14033                hasActivities = r.activities.size() > 0;
14034            }
14035            if (thread != null) {
14036                if (!isCheckinRequest && dumpDetails) {
14037                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14038                }
14039                if (mi == null) {
14040                    mi = new Debug.MemoryInfo();
14041                }
14042                if (dumpDetails || (!brief && !oomOnly)) {
14043                    Debug.getMemoryInfo(pid, mi);
14044                } else {
14045                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14046                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14047                }
14048                if (dumpDetails) {
14049                    if (localOnly) {
14050                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14051                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14052                        if (isCheckinRequest) {
14053                            pw.println();
14054                        }
14055                    } else {
14056                        try {
14057                            pw.flush();
14058                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14059                                    dumpDalvik, innerArgs);
14060                        } catch (RemoteException e) {
14061                            if (!isCheckinRequest) {
14062                                pw.println("Got RemoteException!");
14063                                pw.flush();
14064                            }
14065                        }
14066                    }
14067                }
14068
14069                final long myTotalPss = mi.getTotalPss();
14070                final long myTotalUss = mi.getTotalUss();
14071
14072                synchronized (this) {
14073                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14074                        // Record this for posterity if the process has been stable.
14075                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14076                    }
14077                }
14078
14079                if (!isCheckinRequest && mi != null) {
14080                    totalPss += myTotalPss;
14081                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14082                            (hasActivities ? " / activities)" : ")"),
14083                            r.processName, myTotalPss, pid, hasActivities);
14084                    procMems.add(pssItem);
14085                    procMemsMap.put(pid, pssItem);
14086
14087                    nativePss += mi.nativePss;
14088                    dalvikPss += mi.dalvikPss;
14089                    otherPss += mi.otherPss;
14090                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14091                        long mem = mi.getOtherPss(j);
14092                        miscPss[j] += mem;
14093                        otherPss -= mem;
14094                    }
14095
14096                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14097                        cachedPss += myTotalPss;
14098                    }
14099
14100                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14101                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14102                                || oomIndex == (oomPss.length-1)) {
14103                            oomPss[oomIndex] += myTotalPss;
14104                            if (oomProcs[oomIndex] == null) {
14105                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14106                            }
14107                            oomProcs[oomIndex].add(pssItem);
14108                            break;
14109                        }
14110                    }
14111                }
14112            }
14113        }
14114
14115        long nativeProcTotalPss = 0;
14116
14117        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14118            // If we are showing aggregations, also look for native processes to
14119            // include so that our aggregations are more accurate.
14120            updateCpuStatsNow();
14121            synchronized (mProcessCpuTracker) {
14122                final int N = mProcessCpuTracker.countStats();
14123                for (int i=0; i<N; i++) {
14124                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14125                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14126                        if (mi == null) {
14127                            mi = new Debug.MemoryInfo();
14128                        }
14129                        if (!brief && !oomOnly) {
14130                            Debug.getMemoryInfo(st.pid, mi);
14131                        } else {
14132                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14133                            mi.nativePrivateDirty = (int)tmpLong[0];
14134                        }
14135
14136                        final long myTotalPss = mi.getTotalPss();
14137                        totalPss += myTotalPss;
14138                        nativeProcTotalPss += myTotalPss;
14139
14140                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14141                                st.name, myTotalPss, st.pid, false);
14142                        procMems.add(pssItem);
14143
14144                        nativePss += mi.nativePss;
14145                        dalvikPss += mi.dalvikPss;
14146                        otherPss += mi.otherPss;
14147                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14148                            long mem = mi.getOtherPss(j);
14149                            miscPss[j] += mem;
14150                            otherPss -= mem;
14151                        }
14152                        oomPss[0] += myTotalPss;
14153                        if (oomProcs[0] == null) {
14154                            oomProcs[0] = new ArrayList<MemItem>();
14155                        }
14156                        oomProcs[0].add(pssItem);
14157                    }
14158                }
14159            }
14160
14161            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14162
14163            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14164            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14165            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14166            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14167                String label = Debug.MemoryInfo.getOtherLabel(j);
14168                catMems.add(new MemItem(label, label, miscPss[j], j));
14169            }
14170
14171            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14172            for (int j=0; j<oomPss.length; j++) {
14173                if (oomPss[j] != 0) {
14174                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14175                            : DUMP_MEM_OOM_LABEL[j];
14176                    MemItem item = new MemItem(label, label, oomPss[j],
14177                            DUMP_MEM_OOM_ADJ[j]);
14178                    item.subitems = oomProcs[j];
14179                    oomMems.add(item);
14180                }
14181            }
14182
14183            if (!brief && !oomOnly && !isCompact) {
14184                pw.println();
14185                pw.println("Total PSS by process:");
14186                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14187                pw.println();
14188            }
14189            if (!isCompact) {
14190                pw.println("Total PSS by OOM adjustment:");
14191            }
14192            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14193            if (!brief && !oomOnly) {
14194                PrintWriter out = categoryPw != null ? categoryPw : pw;
14195                if (!isCompact) {
14196                    out.println();
14197                    out.println("Total PSS by category:");
14198                }
14199                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14200            }
14201            if (!isCompact) {
14202                pw.println();
14203            }
14204            MemInfoReader memInfo = new MemInfoReader();
14205            memInfo.readMemInfo();
14206            if (nativeProcTotalPss > 0) {
14207                synchronized (this) {
14208                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14209                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14210                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14211                }
14212            }
14213            if (!brief) {
14214                if (!isCompact) {
14215                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14216                    pw.print(" kB (status ");
14217                    switch (mLastMemoryLevel) {
14218                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14219                            pw.println("normal)");
14220                            break;
14221                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14222                            pw.println("moderate)");
14223                            break;
14224                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14225                            pw.println("low)");
14226                            break;
14227                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14228                            pw.println("critical)");
14229                            break;
14230                        default:
14231                            pw.print(mLastMemoryLevel);
14232                            pw.println(")");
14233                            break;
14234                    }
14235                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14236                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14237                            pw.print(cachedPss); pw.print(" cached pss + ");
14238                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14239                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14240                } else {
14241                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14242                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14243                            + memInfo.getFreeSizeKb()); pw.print(",");
14244                    pw.println(totalPss - cachedPss);
14245                }
14246            }
14247            if (!isCompact) {
14248                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14249                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14250                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14251                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14252                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14253                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14254                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14255            }
14256            if (!brief) {
14257                if (memInfo.getZramTotalSizeKb() != 0) {
14258                    if (!isCompact) {
14259                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14260                                pw.print(" kB physical used for ");
14261                                pw.print(memInfo.getSwapTotalSizeKb()
14262                                        - memInfo.getSwapFreeSizeKb());
14263                                pw.print(" kB in swap (");
14264                                pw.print(memInfo.getSwapTotalSizeKb());
14265                                pw.println(" kB total swap)");
14266                    } else {
14267                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14268                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14269                                pw.println(memInfo.getSwapFreeSizeKb());
14270                    }
14271                }
14272                final long[] ksm = getKsmInfo();
14273                if (!isCompact) {
14274                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14275                            || ksm[KSM_VOLATILE] != 0) {
14276                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14277                                pw.print(" kB saved from shared ");
14278                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14279                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14280                                pw.print(" kB unshared; ");
14281                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14282                    }
14283                    pw.print("   Tuning: ");
14284                    pw.print(ActivityManager.staticGetMemoryClass());
14285                    pw.print(" (large ");
14286                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14287                    pw.print("), oom ");
14288                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14289                    pw.print(" kB");
14290                    pw.print(", restore limit ");
14291                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14292                    pw.print(" kB");
14293                    if (ActivityManager.isLowRamDeviceStatic()) {
14294                        pw.print(" (low-ram)");
14295                    }
14296                    if (ActivityManager.isHighEndGfx()) {
14297                        pw.print(" (high-end-gfx)");
14298                    }
14299                    pw.println();
14300                } else {
14301                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14302                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14303                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14304                    pw.print("tuning,");
14305                    pw.print(ActivityManager.staticGetMemoryClass());
14306                    pw.print(',');
14307                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14308                    pw.print(',');
14309                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14310                    if (ActivityManager.isLowRamDeviceStatic()) {
14311                        pw.print(",low-ram");
14312                    }
14313                    if (ActivityManager.isHighEndGfx()) {
14314                        pw.print(",high-end-gfx");
14315                    }
14316                    pw.println();
14317                }
14318            }
14319        }
14320    }
14321
14322    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14323            String name) {
14324        sb.append("  ");
14325        sb.append(ProcessList.makeOomAdjString(oomAdj));
14326        sb.append(' ');
14327        sb.append(ProcessList.makeProcStateString(procState));
14328        sb.append(' ');
14329        ProcessList.appendRamKb(sb, pss);
14330        sb.append(" kB: ");
14331        sb.append(name);
14332    }
14333
14334    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14335        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14336        sb.append(" (");
14337        sb.append(mi.pid);
14338        sb.append(") ");
14339        sb.append(mi.adjType);
14340        sb.append('\n');
14341        if (mi.adjReason != null) {
14342            sb.append("                      ");
14343            sb.append(mi.adjReason);
14344            sb.append('\n');
14345        }
14346    }
14347
14348    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14349        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14350        for (int i=0, N=memInfos.size(); i<N; i++) {
14351            ProcessMemInfo mi = memInfos.get(i);
14352            infoMap.put(mi.pid, mi);
14353        }
14354        updateCpuStatsNow();
14355        synchronized (mProcessCpuTracker) {
14356            final int N = mProcessCpuTracker.countStats();
14357            for (int i=0; i<N; i++) {
14358                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14359                if (st.vsize > 0) {
14360                    long pss = Debug.getPss(st.pid, null);
14361                    if (pss > 0) {
14362                        if (infoMap.indexOfKey(st.pid) < 0) {
14363                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14364                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14365                            mi.pss = pss;
14366                            memInfos.add(mi);
14367                        }
14368                    }
14369                }
14370            }
14371        }
14372
14373        long totalPss = 0;
14374        for (int i=0, N=memInfos.size(); i<N; i++) {
14375            ProcessMemInfo mi = memInfos.get(i);
14376            if (mi.pss == 0) {
14377                mi.pss = Debug.getPss(mi.pid, null);
14378            }
14379            totalPss += mi.pss;
14380        }
14381        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14382            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14383                if (lhs.oomAdj != rhs.oomAdj) {
14384                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14385                }
14386                if (lhs.pss != rhs.pss) {
14387                    return lhs.pss < rhs.pss ? 1 : -1;
14388                }
14389                return 0;
14390            }
14391        });
14392
14393        StringBuilder tag = new StringBuilder(128);
14394        StringBuilder stack = new StringBuilder(128);
14395        tag.append("Low on memory -- ");
14396        appendMemBucket(tag, totalPss, "total", false);
14397        appendMemBucket(stack, totalPss, "total", true);
14398
14399        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14400        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14401        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14402
14403        boolean firstLine = true;
14404        int lastOomAdj = Integer.MIN_VALUE;
14405        long extraNativeRam = 0;
14406        long cachedPss = 0;
14407        for (int i=0, N=memInfos.size(); i<N; i++) {
14408            ProcessMemInfo mi = memInfos.get(i);
14409
14410            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14411                cachedPss += mi.pss;
14412            }
14413
14414            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14415                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14416                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14417                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14418                if (lastOomAdj != mi.oomAdj) {
14419                    lastOomAdj = mi.oomAdj;
14420                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14421                        tag.append(" / ");
14422                    }
14423                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14424                        if (firstLine) {
14425                            stack.append(":");
14426                            firstLine = false;
14427                        }
14428                        stack.append("\n\t at ");
14429                    } else {
14430                        stack.append("$");
14431                    }
14432                } else {
14433                    tag.append(" ");
14434                    stack.append("$");
14435                }
14436                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14437                    appendMemBucket(tag, mi.pss, mi.name, false);
14438                }
14439                appendMemBucket(stack, mi.pss, mi.name, true);
14440                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14441                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14442                    stack.append("(");
14443                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14444                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14445                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14446                            stack.append(":");
14447                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14448                        }
14449                    }
14450                    stack.append(")");
14451                }
14452            }
14453
14454            appendMemInfo(fullNativeBuilder, mi);
14455            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14456                // The short form only has native processes that are >= 1MB.
14457                if (mi.pss >= 1000) {
14458                    appendMemInfo(shortNativeBuilder, mi);
14459                } else {
14460                    extraNativeRam += mi.pss;
14461                }
14462            } else {
14463                // Short form has all other details, but if we have collected RAM
14464                // from smaller native processes let's dump a summary of that.
14465                if (extraNativeRam > 0) {
14466                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14467                            -1, extraNativeRam, "(Other native)");
14468                    shortNativeBuilder.append('\n');
14469                    extraNativeRam = 0;
14470                }
14471                appendMemInfo(fullJavaBuilder, mi);
14472            }
14473        }
14474
14475        fullJavaBuilder.append("           ");
14476        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14477        fullJavaBuilder.append(" kB: TOTAL\n");
14478
14479        MemInfoReader memInfo = new MemInfoReader();
14480        memInfo.readMemInfo();
14481        final long[] infos = memInfo.getRawInfo();
14482
14483        StringBuilder memInfoBuilder = new StringBuilder(1024);
14484        Debug.getMemInfo(infos);
14485        memInfoBuilder.append("  MemInfo: ");
14486        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14487        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14488        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14489        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14490        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14491        memInfoBuilder.append("           ");
14492        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14493        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14494        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14495        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14496        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14497            memInfoBuilder.append("  ZRAM: ");
14498            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14499            memInfoBuilder.append(" kB RAM, ");
14500            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14501            memInfoBuilder.append(" kB swap total, ");
14502            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14503            memInfoBuilder.append(" kB swap free\n");
14504        }
14505        final long[] ksm = getKsmInfo();
14506        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14507                || ksm[KSM_VOLATILE] != 0) {
14508            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14509            memInfoBuilder.append(" kB saved from shared ");
14510            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14511            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14512            memInfoBuilder.append(" kB unshared; ");
14513            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14514        }
14515        memInfoBuilder.append("  Free RAM: ");
14516        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14517                + memInfo.getFreeSizeKb());
14518        memInfoBuilder.append(" kB\n");
14519        memInfoBuilder.append("  Used RAM: ");
14520        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14521        memInfoBuilder.append(" kB\n");
14522        memInfoBuilder.append("  Lost RAM: ");
14523        memInfoBuilder.append(memInfo.getTotalSizeKb()
14524                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14525                - memInfo.getKernelUsedSizeKb());
14526        memInfoBuilder.append(" kB\n");
14527        Slog.i(TAG, "Low on memory:");
14528        Slog.i(TAG, shortNativeBuilder.toString());
14529        Slog.i(TAG, fullJavaBuilder.toString());
14530        Slog.i(TAG, memInfoBuilder.toString());
14531
14532        StringBuilder dropBuilder = new StringBuilder(1024);
14533        /*
14534        StringWriter oomSw = new StringWriter();
14535        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14536        StringWriter catSw = new StringWriter();
14537        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14538        String[] emptyArgs = new String[] { };
14539        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14540        oomPw.flush();
14541        String oomString = oomSw.toString();
14542        */
14543        dropBuilder.append("Low on memory:");
14544        dropBuilder.append(stack);
14545        dropBuilder.append('\n');
14546        dropBuilder.append(fullNativeBuilder);
14547        dropBuilder.append(fullJavaBuilder);
14548        dropBuilder.append('\n');
14549        dropBuilder.append(memInfoBuilder);
14550        dropBuilder.append('\n');
14551        /*
14552        dropBuilder.append(oomString);
14553        dropBuilder.append('\n');
14554        */
14555        StringWriter catSw = new StringWriter();
14556        synchronized (ActivityManagerService.this) {
14557            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14558            String[] emptyArgs = new String[] { };
14559            catPw.println();
14560            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14561            catPw.println();
14562            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14563                    false, false, null);
14564            catPw.println();
14565            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14566            catPw.flush();
14567        }
14568        dropBuilder.append(catSw.toString());
14569        addErrorToDropBox("lowmem", null, "system_server", null,
14570                null, tag.toString(), dropBuilder.toString(), null, null);
14571        //Slog.i(TAG, "Sent to dropbox:");
14572        //Slog.i(TAG, dropBuilder.toString());
14573        synchronized (ActivityManagerService.this) {
14574            long now = SystemClock.uptimeMillis();
14575            if (mLastMemUsageReportTime < now) {
14576                mLastMemUsageReportTime = now;
14577            }
14578        }
14579    }
14580
14581    /**
14582     * Searches array of arguments for the specified string
14583     * @param args array of argument strings
14584     * @param value value to search for
14585     * @return true if the value is contained in the array
14586     */
14587    private static boolean scanArgs(String[] args, String value) {
14588        if (args != null) {
14589            for (String arg : args) {
14590                if (value.equals(arg)) {
14591                    return true;
14592                }
14593            }
14594        }
14595        return false;
14596    }
14597
14598    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14599            ContentProviderRecord cpr, boolean always) {
14600        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14601
14602        if (!inLaunching || always) {
14603            synchronized (cpr) {
14604                cpr.launchingApp = null;
14605                cpr.notifyAll();
14606            }
14607            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14608            String names[] = cpr.info.authority.split(";");
14609            for (int j = 0; j < names.length; j++) {
14610                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14611            }
14612        }
14613
14614        for (int i=0; i<cpr.connections.size(); i++) {
14615            ContentProviderConnection conn = cpr.connections.get(i);
14616            if (conn.waiting) {
14617                // If this connection is waiting for the provider, then we don't
14618                // need to mess with its process unless we are always removing
14619                // or for some reason the provider is not currently launching.
14620                if (inLaunching && !always) {
14621                    continue;
14622                }
14623            }
14624            ProcessRecord capp = conn.client;
14625            conn.dead = true;
14626            if (conn.stableCount > 0) {
14627                if (!capp.persistent && capp.thread != null
14628                        && capp.pid != 0
14629                        && capp.pid != MY_PID) {
14630                    capp.kill("depends on provider "
14631                            + cpr.name.flattenToShortString()
14632                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14633                }
14634            } else if (capp.thread != null && conn.provider.provider != null) {
14635                try {
14636                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14637                } catch (RemoteException e) {
14638                }
14639                // In the protocol here, we don't expect the client to correctly
14640                // clean up this connection, we'll just remove it.
14641                cpr.connections.remove(i);
14642                conn.client.conProviders.remove(conn);
14643            }
14644        }
14645
14646        if (inLaunching && always) {
14647            mLaunchingProviders.remove(cpr);
14648        }
14649        return inLaunching;
14650    }
14651
14652    /**
14653     * Main code for cleaning up a process when it has gone away.  This is
14654     * called both as a result of the process dying, or directly when stopping
14655     * a process when running in single process mode.
14656     *
14657     * @return Returns true if the given process has been restarted, so the
14658     * app that was passed in must remain on the process lists.
14659     */
14660    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14661            boolean restarting, boolean allowRestart, int index) {
14662        if (index >= 0) {
14663            removeLruProcessLocked(app);
14664            ProcessList.remove(app.pid);
14665        }
14666
14667        mProcessesToGc.remove(app);
14668        mPendingPssProcesses.remove(app);
14669
14670        // Dismiss any open dialogs.
14671        if (app.crashDialog != null && !app.forceCrashReport) {
14672            app.crashDialog.dismiss();
14673            app.crashDialog = null;
14674        }
14675        if (app.anrDialog != null) {
14676            app.anrDialog.dismiss();
14677            app.anrDialog = null;
14678        }
14679        if (app.waitDialog != null) {
14680            app.waitDialog.dismiss();
14681            app.waitDialog = null;
14682        }
14683
14684        app.crashing = false;
14685        app.notResponding = false;
14686
14687        app.resetPackageList(mProcessStats);
14688        app.unlinkDeathRecipient();
14689        app.makeInactive(mProcessStats);
14690        app.waitingToKill = null;
14691        app.forcingToForeground = null;
14692        updateProcessForegroundLocked(app, false, false);
14693        app.foregroundActivities = false;
14694        app.hasShownUi = false;
14695        app.treatLikeActivity = false;
14696        app.hasAboveClient = false;
14697        app.hasClientActivities = false;
14698
14699        mServices.killServicesLocked(app, allowRestart);
14700
14701        boolean restart = false;
14702
14703        // Remove published content providers.
14704        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14705            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14706            final boolean always = app.bad || !allowRestart;
14707            if (removeDyingProviderLocked(app, cpr, always) || always) {
14708                // We left the provider in the launching list, need to
14709                // restart it.
14710                restart = true;
14711            }
14712
14713            cpr.provider = null;
14714            cpr.proc = null;
14715        }
14716        app.pubProviders.clear();
14717
14718        // Take care of any launching providers waiting for this process.
14719        if (checkAppInLaunchingProvidersLocked(app, false)) {
14720            restart = true;
14721        }
14722
14723        // Unregister from connected content providers.
14724        if (!app.conProviders.isEmpty()) {
14725            for (int i=0; i<app.conProviders.size(); i++) {
14726                ContentProviderConnection conn = app.conProviders.get(i);
14727                conn.provider.connections.remove(conn);
14728            }
14729            app.conProviders.clear();
14730        }
14731
14732        // At this point there may be remaining entries in mLaunchingProviders
14733        // where we were the only one waiting, so they are no longer of use.
14734        // Look for these and clean up if found.
14735        // XXX Commented out for now.  Trying to figure out a way to reproduce
14736        // the actual situation to identify what is actually going on.
14737        if (false) {
14738            for (int i=0; i<mLaunchingProviders.size(); i++) {
14739                ContentProviderRecord cpr = (ContentProviderRecord)
14740                        mLaunchingProviders.get(i);
14741                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14742                    synchronized (cpr) {
14743                        cpr.launchingApp = null;
14744                        cpr.notifyAll();
14745                    }
14746                }
14747            }
14748        }
14749
14750        skipCurrentReceiverLocked(app);
14751
14752        // Unregister any receivers.
14753        for (int i=app.receivers.size()-1; i>=0; i--) {
14754            removeReceiverLocked(app.receivers.valueAt(i));
14755        }
14756        app.receivers.clear();
14757
14758        // If the app is undergoing backup, tell the backup manager about it
14759        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14760            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14761                    + mBackupTarget.appInfo + " died during backup");
14762            try {
14763                IBackupManager bm = IBackupManager.Stub.asInterface(
14764                        ServiceManager.getService(Context.BACKUP_SERVICE));
14765                bm.agentDisconnected(app.info.packageName);
14766            } catch (RemoteException e) {
14767                // can't happen; backup manager is local
14768            }
14769        }
14770
14771        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14772            ProcessChangeItem item = mPendingProcessChanges.get(i);
14773            if (item.pid == app.pid) {
14774                mPendingProcessChanges.remove(i);
14775                mAvailProcessChanges.add(item);
14776            }
14777        }
14778        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14779
14780        // If the caller is restarting this app, then leave it in its
14781        // current lists and let the caller take care of it.
14782        if (restarting) {
14783            return false;
14784        }
14785
14786        if (!app.persistent || app.isolated) {
14787            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14788                    "Removing non-persistent process during cleanup: " + app);
14789            mProcessNames.remove(app.processName, app.uid);
14790            mIsolatedProcesses.remove(app.uid);
14791            if (mHeavyWeightProcess == app) {
14792                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14793                        mHeavyWeightProcess.userId, 0));
14794                mHeavyWeightProcess = null;
14795            }
14796        } else if (!app.removed) {
14797            // This app is persistent, so we need to keep its record around.
14798            // If it is not already on the pending app list, add it there
14799            // and start a new process for it.
14800            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14801                mPersistentStartingProcesses.add(app);
14802                restart = true;
14803            }
14804        }
14805        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14806                "Clean-up removing on hold: " + app);
14807        mProcessesOnHold.remove(app);
14808
14809        if (app == mHomeProcess) {
14810            mHomeProcess = null;
14811        }
14812        if (app == mPreviousProcess) {
14813            mPreviousProcess = null;
14814        }
14815
14816        if (restart && !app.isolated) {
14817            // We have components that still need to be running in the
14818            // process, so re-launch it.
14819            if (index < 0) {
14820                ProcessList.remove(app.pid);
14821            }
14822            mProcessNames.put(app.processName, app.uid, app);
14823            startProcessLocked(app, "restart", app.processName);
14824            return true;
14825        } else if (app.pid > 0 && app.pid != MY_PID) {
14826            // Goodbye!
14827            boolean removed;
14828            synchronized (mPidsSelfLocked) {
14829                mPidsSelfLocked.remove(app.pid);
14830                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14831            }
14832            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14833            if (app.isolated) {
14834                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14835            }
14836            app.setPid(0);
14837        }
14838        return false;
14839    }
14840
14841    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14842        // Look through the content providers we are waiting to have launched,
14843        // and if any run in this process then either schedule a restart of
14844        // the process or kill the client waiting for it if this process has
14845        // gone bad.
14846        int NL = mLaunchingProviders.size();
14847        boolean restart = false;
14848        for (int i=0; i<NL; i++) {
14849            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14850            if (cpr.launchingApp == app) {
14851                if (!alwaysBad && !app.bad) {
14852                    restart = true;
14853                } else {
14854                    removeDyingProviderLocked(app, cpr, true);
14855                    // cpr should have been removed from mLaunchingProviders
14856                    NL = mLaunchingProviders.size();
14857                    i--;
14858                }
14859            }
14860        }
14861        return restart;
14862    }
14863
14864    // =========================================================
14865    // SERVICES
14866    // =========================================================
14867
14868    @Override
14869    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14870            int flags) {
14871        enforceNotIsolatedCaller("getServices");
14872        synchronized (this) {
14873            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14874        }
14875    }
14876
14877    @Override
14878    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14879        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14880        synchronized (this) {
14881            return mServices.getRunningServiceControlPanelLocked(name);
14882        }
14883    }
14884
14885    @Override
14886    public ComponentName startService(IApplicationThread caller, Intent service,
14887            String resolvedType, int userId) {
14888        enforceNotIsolatedCaller("startService");
14889        // Refuse possible leaked file descriptors
14890        if (service != null && service.hasFileDescriptors() == true) {
14891            throw new IllegalArgumentException("File descriptors passed in Intent");
14892        }
14893
14894        if (DEBUG_SERVICE)
14895            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14896        synchronized(this) {
14897            final int callingPid = Binder.getCallingPid();
14898            final int callingUid = Binder.getCallingUid();
14899            final long origId = Binder.clearCallingIdentity();
14900            ComponentName res = mServices.startServiceLocked(caller, service,
14901                    resolvedType, callingPid, callingUid, userId);
14902            Binder.restoreCallingIdentity(origId);
14903            return res;
14904        }
14905    }
14906
14907    ComponentName startServiceInPackage(int uid,
14908            Intent service, String resolvedType, int userId) {
14909        synchronized(this) {
14910            if (DEBUG_SERVICE)
14911                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14912            final long origId = Binder.clearCallingIdentity();
14913            ComponentName res = mServices.startServiceLocked(null, service,
14914                    resolvedType, -1, uid, userId);
14915            Binder.restoreCallingIdentity(origId);
14916            return res;
14917        }
14918    }
14919
14920    @Override
14921    public int stopService(IApplicationThread caller, Intent service,
14922            String resolvedType, int userId) {
14923        enforceNotIsolatedCaller("stopService");
14924        // Refuse possible leaked file descriptors
14925        if (service != null && service.hasFileDescriptors() == true) {
14926            throw new IllegalArgumentException("File descriptors passed in Intent");
14927        }
14928
14929        synchronized(this) {
14930            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14931        }
14932    }
14933
14934    @Override
14935    public IBinder peekService(Intent service, String resolvedType) {
14936        enforceNotIsolatedCaller("peekService");
14937        // Refuse possible leaked file descriptors
14938        if (service != null && service.hasFileDescriptors() == true) {
14939            throw new IllegalArgumentException("File descriptors passed in Intent");
14940        }
14941        synchronized(this) {
14942            return mServices.peekServiceLocked(service, resolvedType);
14943        }
14944    }
14945
14946    @Override
14947    public boolean stopServiceToken(ComponentName className, IBinder token,
14948            int startId) {
14949        synchronized(this) {
14950            return mServices.stopServiceTokenLocked(className, token, startId);
14951        }
14952    }
14953
14954    @Override
14955    public void setServiceForeground(ComponentName className, IBinder token,
14956            int id, Notification notification, boolean removeNotification) {
14957        synchronized(this) {
14958            mServices.setServiceForegroundLocked(className, token, id, notification,
14959                    removeNotification);
14960        }
14961    }
14962
14963    @Override
14964    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14965            boolean requireFull, String name, String callerPackage) {
14966        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14967                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14968    }
14969
14970    int unsafeConvertIncomingUser(int userId) {
14971        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14972                ? mCurrentUserId : userId;
14973    }
14974
14975    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14976            int allowMode, String name, String callerPackage) {
14977        final int callingUserId = UserHandle.getUserId(callingUid);
14978        if (callingUserId == userId) {
14979            return userId;
14980        }
14981
14982        // Note that we may be accessing mCurrentUserId outside of a lock...
14983        // shouldn't be a big deal, if this is being called outside
14984        // of a locked context there is intrinsically a race with
14985        // the value the caller will receive and someone else changing it.
14986        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14987        // we will switch to the calling user if access to the current user fails.
14988        int targetUserId = unsafeConvertIncomingUser(userId);
14989
14990        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14991            final boolean allow;
14992            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14993                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14994                // If the caller has this permission, they always pass go.  And collect $200.
14995                allow = true;
14996            } else if (allowMode == ALLOW_FULL_ONLY) {
14997                // We require full access, sucks to be you.
14998                allow = false;
14999            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15000                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15001                // If the caller does not have either permission, they are always doomed.
15002                allow = false;
15003            } else if (allowMode == ALLOW_NON_FULL) {
15004                // We are blanket allowing non-full access, you lucky caller!
15005                allow = true;
15006            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15007                // We may or may not allow this depending on whether the two users are
15008                // in the same profile.
15009                synchronized (mUserProfileGroupIdsSelfLocked) {
15010                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15011                            UserInfo.NO_PROFILE_GROUP_ID);
15012                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15013                            UserInfo.NO_PROFILE_GROUP_ID);
15014                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15015                            && callingProfile == targetProfile;
15016                }
15017            } else {
15018                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15019            }
15020            if (!allow) {
15021                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15022                    // In this case, they would like to just execute as their
15023                    // owner user instead of failing.
15024                    targetUserId = callingUserId;
15025                } else {
15026                    StringBuilder builder = new StringBuilder(128);
15027                    builder.append("Permission Denial: ");
15028                    builder.append(name);
15029                    if (callerPackage != null) {
15030                        builder.append(" from ");
15031                        builder.append(callerPackage);
15032                    }
15033                    builder.append(" asks to run as user ");
15034                    builder.append(userId);
15035                    builder.append(" but is calling from user ");
15036                    builder.append(UserHandle.getUserId(callingUid));
15037                    builder.append("; this requires ");
15038                    builder.append(INTERACT_ACROSS_USERS_FULL);
15039                    if (allowMode != ALLOW_FULL_ONLY) {
15040                        builder.append(" or ");
15041                        builder.append(INTERACT_ACROSS_USERS);
15042                    }
15043                    String msg = builder.toString();
15044                    Slog.w(TAG, msg);
15045                    throw new SecurityException(msg);
15046                }
15047            }
15048        }
15049        if (!allowAll && targetUserId < 0) {
15050            throw new IllegalArgumentException(
15051                    "Call does not support special user #" + targetUserId);
15052        }
15053        // Check shell permission
15054        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15055            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15056                    targetUserId)) {
15057                throw new SecurityException("Shell does not have permission to access user "
15058                        + targetUserId + "\n " + Debug.getCallers(3));
15059            }
15060        }
15061        return targetUserId;
15062    }
15063
15064    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15065            String className, int flags) {
15066        boolean result = false;
15067        // For apps that don't have pre-defined UIDs, check for permission
15068        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15069            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15070                if (ActivityManager.checkUidPermission(
15071                        INTERACT_ACROSS_USERS,
15072                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15073                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15074                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15075                            + " requests FLAG_SINGLE_USER, but app does not hold "
15076                            + INTERACT_ACROSS_USERS;
15077                    Slog.w(TAG, msg);
15078                    throw new SecurityException(msg);
15079                }
15080                // Permission passed
15081                result = true;
15082            }
15083        } else if ("system".equals(componentProcessName)) {
15084            result = true;
15085        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15086            // Phone app and persistent apps are allowed to export singleuser providers.
15087            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15088                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15089        }
15090        if (DEBUG_MU) {
15091            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15092                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15093        }
15094        return result;
15095    }
15096
15097    /**
15098     * Checks to see if the caller is in the same app as the singleton
15099     * component, or the component is in a special app. It allows special apps
15100     * to export singleton components but prevents exporting singleton
15101     * components for regular apps.
15102     */
15103    boolean isValidSingletonCall(int callingUid, int componentUid) {
15104        int componentAppId = UserHandle.getAppId(componentUid);
15105        return UserHandle.isSameApp(callingUid, componentUid)
15106                || componentAppId == Process.SYSTEM_UID
15107                || componentAppId == Process.PHONE_UID
15108                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15109                        == PackageManager.PERMISSION_GRANTED;
15110    }
15111
15112    public int bindService(IApplicationThread caller, IBinder token,
15113            Intent service, String resolvedType,
15114            IServiceConnection connection, int flags, int userId) {
15115        enforceNotIsolatedCaller("bindService");
15116
15117        // Refuse possible leaked file descriptors
15118        if (service != null && service.hasFileDescriptors() == true) {
15119            throw new IllegalArgumentException("File descriptors passed in Intent");
15120        }
15121
15122        synchronized(this) {
15123            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15124                    connection, flags, userId);
15125        }
15126    }
15127
15128    public boolean unbindService(IServiceConnection connection) {
15129        synchronized (this) {
15130            return mServices.unbindServiceLocked(connection);
15131        }
15132    }
15133
15134    public void publishService(IBinder token, Intent intent, IBinder service) {
15135        // Refuse possible leaked file descriptors
15136        if (intent != null && intent.hasFileDescriptors() == true) {
15137            throw new IllegalArgumentException("File descriptors passed in Intent");
15138        }
15139
15140        synchronized(this) {
15141            if (!(token instanceof ServiceRecord)) {
15142                throw new IllegalArgumentException("Invalid service token");
15143            }
15144            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15145        }
15146    }
15147
15148    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15149        // Refuse possible leaked file descriptors
15150        if (intent != null && intent.hasFileDescriptors() == true) {
15151            throw new IllegalArgumentException("File descriptors passed in Intent");
15152        }
15153
15154        synchronized(this) {
15155            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15156        }
15157    }
15158
15159    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15160        synchronized(this) {
15161            if (!(token instanceof ServiceRecord)) {
15162                throw new IllegalArgumentException("Invalid service token");
15163            }
15164            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15165        }
15166    }
15167
15168    // =========================================================
15169    // BACKUP AND RESTORE
15170    // =========================================================
15171
15172    // Cause the target app to be launched if necessary and its backup agent
15173    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15174    // activity manager to announce its creation.
15175    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15176        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15177        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15178
15179        synchronized(this) {
15180            // !!! TODO: currently no check here that we're already bound
15181            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15182            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15183            synchronized (stats) {
15184                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15185            }
15186
15187            // Backup agent is now in use, its package can't be stopped.
15188            try {
15189                AppGlobals.getPackageManager().setPackageStoppedState(
15190                        app.packageName, false, UserHandle.getUserId(app.uid));
15191            } catch (RemoteException e) {
15192            } catch (IllegalArgumentException e) {
15193                Slog.w(TAG, "Failed trying to unstop package "
15194                        + app.packageName + ": " + e);
15195            }
15196
15197            BackupRecord r = new BackupRecord(ss, app, backupMode);
15198            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15199                    ? new ComponentName(app.packageName, app.backupAgentName)
15200                    : new ComponentName("android", "FullBackupAgent");
15201            // startProcessLocked() returns existing proc's record if it's already running
15202            ProcessRecord proc = startProcessLocked(app.processName, app,
15203                    false, 0, "backup", hostingName, false, false, false);
15204            if (proc == null) {
15205                Slog.e(TAG, "Unable to start backup agent process " + r);
15206                return false;
15207            }
15208
15209            r.app = proc;
15210            mBackupTarget = r;
15211            mBackupAppName = app.packageName;
15212
15213            // Try not to kill the process during backup
15214            updateOomAdjLocked(proc);
15215
15216            // If the process is already attached, schedule the creation of the backup agent now.
15217            // If it is not yet live, this will be done when it attaches to the framework.
15218            if (proc.thread != null) {
15219                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15220                try {
15221                    proc.thread.scheduleCreateBackupAgent(app,
15222                            compatibilityInfoForPackageLocked(app), backupMode);
15223                } catch (RemoteException e) {
15224                    // Will time out on the backup manager side
15225                }
15226            } else {
15227                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15228            }
15229            // Invariants: at this point, the target app process exists and the application
15230            // is either already running or in the process of coming up.  mBackupTarget and
15231            // mBackupAppName describe the app, so that when it binds back to the AM we
15232            // know that it's scheduled for a backup-agent operation.
15233        }
15234
15235        return true;
15236    }
15237
15238    @Override
15239    public void clearPendingBackup() {
15240        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15241        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15242
15243        synchronized (this) {
15244            mBackupTarget = null;
15245            mBackupAppName = null;
15246        }
15247    }
15248
15249    // A backup agent has just come up
15250    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15251        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15252                + " = " + agent);
15253
15254        synchronized(this) {
15255            if (!agentPackageName.equals(mBackupAppName)) {
15256                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15257                return;
15258            }
15259        }
15260
15261        long oldIdent = Binder.clearCallingIdentity();
15262        try {
15263            IBackupManager bm = IBackupManager.Stub.asInterface(
15264                    ServiceManager.getService(Context.BACKUP_SERVICE));
15265            bm.agentConnected(agentPackageName, agent);
15266        } catch (RemoteException e) {
15267            // can't happen; the backup manager service is local
15268        } catch (Exception e) {
15269            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15270            e.printStackTrace();
15271        } finally {
15272            Binder.restoreCallingIdentity(oldIdent);
15273        }
15274    }
15275
15276    // done with this agent
15277    public void unbindBackupAgent(ApplicationInfo appInfo) {
15278        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15279        if (appInfo == null) {
15280            Slog.w(TAG, "unbind backup agent for null app");
15281            return;
15282        }
15283
15284        synchronized(this) {
15285            try {
15286                if (mBackupAppName == null) {
15287                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15288                    return;
15289                }
15290
15291                if (!mBackupAppName.equals(appInfo.packageName)) {
15292                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15293                    return;
15294                }
15295
15296                // Not backing this app up any more; reset its OOM adjustment
15297                final ProcessRecord proc = mBackupTarget.app;
15298                updateOomAdjLocked(proc);
15299
15300                // If the app crashed during backup, 'thread' will be null here
15301                if (proc.thread != null) {
15302                    try {
15303                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15304                                compatibilityInfoForPackageLocked(appInfo));
15305                    } catch (Exception e) {
15306                        Slog.e(TAG, "Exception when unbinding backup agent:");
15307                        e.printStackTrace();
15308                    }
15309                }
15310            } finally {
15311                mBackupTarget = null;
15312                mBackupAppName = null;
15313            }
15314        }
15315    }
15316    // =========================================================
15317    // BROADCASTS
15318    // =========================================================
15319
15320    private final List getStickiesLocked(String action, IntentFilter filter,
15321            List cur, int userId) {
15322        final ContentResolver resolver = mContext.getContentResolver();
15323        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15324        if (stickies == null) {
15325            return cur;
15326        }
15327        final ArrayList<Intent> list = stickies.get(action);
15328        if (list == null) {
15329            return cur;
15330        }
15331        int N = list.size();
15332        for (int i=0; i<N; i++) {
15333            Intent intent = list.get(i);
15334            if (filter.match(resolver, intent, true, TAG) >= 0) {
15335                if (cur == null) {
15336                    cur = new ArrayList<Intent>();
15337                }
15338                cur.add(intent);
15339            }
15340        }
15341        return cur;
15342    }
15343
15344    boolean isPendingBroadcastProcessLocked(int pid) {
15345        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15346                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15347    }
15348
15349    void skipPendingBroadcastLocked(int pid) {
15350            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15351            for (BroadcastQueue queue : mBroadcastQueues) {
15352                queue.skipPendingBroadcastLocked(pid);
15353            }
15354    }
15355
15356    // The app just attached; send any pending broadcasts that it should receive
15357    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15358        boolean didSomething = false;
15359        for (BroadcastQueue queue : mBroadcastQueues) {
15360            didSomething |= queue.sendPendingBroadcastsLocked(app);
15361        }
15362        return didSomething;
15363    }
15364
15365    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15366            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15367        enforceNotIsolatedCaller("registerReceiver");
15368        int callingUid;
15369        int callingPid;
15370        synchronized(this) {
15371            ProcessRecord callerApp = null;
15372            if (caller != null) {
15373                callerApp = getRecordForAppLocked(caller);
15374                if (callerApp == null) {
15375                    throw new SecurityException(
15376                            "Unable to find app for caller " + caller
15377                            + " (pid=" + Binder.getCallingPid()
15378                            + ") when registering receiver " + receiver);
15379                }
15380                if (callerApp.info.uid != Process.SYSTEM_UID &&
15381                        !callerApp.pkgList.containsKey(callerPackage) &&
15382                        !"android".equals(callerPackage)) {
15383                    throw new SecurityException("Given caller package " + callerPackage
15384                            + " is not running in process " + callerApp);
15385                }
15386                callingUid = callerApp.info.uid;
15387                callingPid = callerApp.pid;
15388            } else {
15389                callerPackage = null;
15390                callingUid = Binder.getCallingUid();
15391                callingPid = Binder.getCallingPid();
15392            }
15393
15394            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15395                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15396
15397            List allSticky = null;
15398
15399            // Look for any matching sticky broadcasts...
15400            Iterator actions = filter.actionsIterator();
15401            if (actions != null) {
15402                while (actions.hasNext()) {
15403                    String action = (String)actions.next();
15404                    allSticky = getStickiesLocked(action, filter, allSticky,
15405                            UserHandle.USER_ALL);
15406                    allSticky = getStickiesLocked(action, filter, allSticky,
15407                            UserHandle.getUserId(callingUid));
15408                }
15409            } else {
15410                allSticky = getStickiesLocked(null, filter, allSticky,
15411                        UserHandle.USER_ALL);
15412                allSticky = getStickiesLocked(null, filter, allSticky,
15413                        UserHandle.getUserId(callingUid));
15414            }
15415
15416            // The first sticky in the list is returned directly back to
15417            // the client.
15418            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15419
15420            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15421                    + ": " + sticky);
15422
15423            if (receiver == null) {
15424                return sticky;
15425            }
15426
15427            ReceiverList rl
15428                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15429            if (rl == null) {
15430                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15431                        userId, receiver);
15432                if (rl.app != null) {
15433                    rl.app.receivers.add(rl);
15434                } else {
15435                    try {
15436                        receiver.asBinder().linkToDeath(rl, 0);
15437                    } catch (RemoteException e) {
15438                        return sticky;
15439                    }
15440                    rl.linkedToDeath = true;
15441                }
15442                mRegisteredReceivers.put(receiver.asBinder(), rl);
15443            } else if (rl.uid != callingUid) {
15444                throw new IllegalArgumentException(
15445                        "Receiver requested to register for uid " + callingUid
15446                        + " was previously registered for uid " + rl.uid);
15447            } else if (rl.pid != callingPid) {
15448                throw new IllegalArgumentException(
15449                        "Receiver requested to register for pid " + callingPid
15450                        + " was previously registered for pid " + rl.pid);
15451            } else if (rl.userId != userId) {
15452                throw new IllegalArgumentException(
15453                        "Receiver requested to register for user " + userId
15454                        + " was previously registered for user " + rl.userId);
15455            }
15456            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15457                    permission, callingUid, userId);
15458            rl.add(bf);
15459            if (!bf.debugCheck()) {
15460                Slog.w(TAG, "==> For Dynamic broadast");
15461            }
15462            mReceiverResolver.addFilter(bf);
15463
15464            // Enqueue broadcasts for all existing stickies that match
15465            // this filter.
15466            if (allSticky != null) {
15467                ArrayList receivers = new ArrayList();
15468                receivers.add(bf);
15469
15470                int N = allSticky.size();
15471                for (int i=0; i<N; i++) {
15472                    Intent intent = (Intent)allSticky.get(i);
15473                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15474                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15475                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15476                            null, null, false, true, true, -1);
15477                    queue.enqueueParallelBroadcastLocked(r);
15478                    queue.scheduleBroadcastsLocked();
15479                }
15480            }
15481
15482            return sticky;
15483        }
15484    }
15485
15486    public void unregisterReceiver(IIntentReceiver receiver) {
15487        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15488
15489        final long origId = Binder.clearCallingIdentity();
15490        try {
15491            boolean doTrim = false;
15492
15493            synchronized(this) {
15494                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15495                if (rl != null) {
15496                    if (rl.curBroadcast != null) {
15497                        BroadcastRecord r = rl.curBroadcast;
15498                        final boolean doNext = finishReceiverLocked(
15499                                receiver.asBinder(), r.resultCode, r.resultData,
15500                                r.resultExtras, r.resultAbort);
15501                        if (doNext) {
15502                            doTrim = true;
15503                            r.queue.processNextBroadcast(false);
15504                        }
15505                    }
15506
15507                    if (rl.app != null) {
15508                        rl.app.receivers.remove(rl);
15509                    }
15510                    removeReceiverLocked(rl);
15511                    if (rl.linkedToDeath) {
15512                        rl.linkedToDeath = false;
15513                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15514                    }
15515                }
15516            }
15517
15518            // If we actually concluded any broadcasts, we might now be able
15519            // to trim the recipients' apps from our working set
15520            if (doTrim) {
15521                trimApplications();
15522                return;
15523            }
15524
15525        } finally {
15526            Binder.restoreCallingIdentity(origId);
15527        }
15528    }
15529
15530    void removeReceiverLocked(ReceiverList rl) {
15531        mRegisteredReceivers.remove(rl.receiver.asBinder());
15532        int N = rl.size();
15533        for (int i=0; i<N; i++) {
15534            mReceiverResolver.removeFilter(rl.get(i));
15535        }
15536    }
15537
15538    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15539        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15540            ProcessRecord r = mLruProcesses.get(i);
15541            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15542                try {
15543                    r.thread.dispatchPackageBroadcast(cmd, packages);
15544                } catch (RemoteException ex) {
15545                }
15546            }
15547        }
15548    }
15549
15550    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15551            int callingUid, int[] users) {
15552        List<ResolveInfo> receivers = null;
15553        try {
15554            HashSet<ComponentName> singleUserReceivers = null;
15555            boolean scannedFirstReceivers = false;
15556            for (int user : users) {
15557                // Skip users that have Shell restrictions
15558                if (callingUid == Process.SHELL_UID
15559                        && getUserManagerLocked().hasUserRestriction(
15560                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15561                    continue;
15562                }
15563                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15564                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15565                if (user != 0 && newReceivers != null) {
15566                    // If this is not the primary user, we need to check for
15567                    // any receivers that should be filtered out.
15568                    for (int i=0; i<newReceivers.size(); i++) {
15569                        ResolveInfo ri = newReceivers.get(i);
15570                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15571                            newReceivers.remove(i);
15572                            i--;
15573                        }
15574                    }
15575                }
15576                if (newReceivers != null && newReceivers.size() == 0) {
15577                    newReceivers = null;
15578                }
15579                if (receivers == null) {
15580                    receivers = newReceivers;
15581                } else if (newReceivers != null) {
15582                    // We need to concatenate the additional receivers
15583                    // found with what we have do far.  This would be easy,
15584                    // but we also need to de-dup any receivers that are
15585                    // singleUser.
15586                    if (!scannedFirstReceivers) {
15587                        // Collect any single user receivers we had already retrieved.
15588                        scannedFirstReceivers = true;
15589                        for (int i=0; i<receivers.size(); i++) {
15590                            ResolveInfo ri = receivers.get(i);
15591                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15592                                ComponentName cn = new ComponentName(
15593                                        ri.activityInfo.packageName, ri.activityInfo.name);
15594                                if (singleUserReceivers == null) {
15595                                    singleUserReceivers = new HashSet<ComponentName>();
15596                                }
15597                                singleUserReceivers.add(cn);
15598                            }
15599                        }
15600                    }
15601                    // Add the new results to the existing results, tracking
15602                    // and de-dupping single user receivers.
15603                    for (int i=0; i<newReceivers.size(); i++) {
15604                        ResolveInfo ri = newReceivers.get(i);
15605                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15606                            ComponentName cn = new ComponentName(
15607                                    ri.activityInfo.packageName, ri.activityInfo.name);
15608                            if (singleUserReceivers == null) {
15609                                singleUserReceivers = new HashSet<ComponentName>();
15610                            }
15611                            if (!singleUserReceivers.contains(cn)) {
15612                                singleUserReceivers.add(cn);
15613                                receivers.add(ri);
15614                            }
15615                        } else {
15616                            receivers.add(ri);
15617                        }
15618                    }
15619                }
15620            }
15621        } catch (RemoteException ex) {
15622            // pm is in same process, this will never happen.
15623        }
15624        return receivers;
15625    }
15626
15627    private final int broadcastIntentLocked(ProcessRecord callerApp,
15628            String callerPackage, Intent intent, String resolvedType,
15629            IIntentReceiver resultTo, int resultCode, String resultData,
15630            Bundle map, String requiredPermission, int appOp,
15631            boolean ordered, boolean sticky, int callingPid, int callingUid,
15632            int userId) {
15633        intent = new Intent(intent);
15634
15635        // By default broadcasts do not go to stopped apps.
15636        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15637
15638        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15639            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15640            + " ordered=" + ordered + " userid=" + userId);
15641        if ((resultTo != null) && !ordered) {
15642            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15643        }
15644
15645        userId = handleIncomingUser(callingPid, callingUid, userId,
15646                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15647
15648        // Make sure that the user who is receiving this broadcast is started.
15649        // If not, we will just skip it.
15650
15651        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15652            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15653                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15654                Slog.w(TAG, "Skipping broadcast of " + intent
15655                        + ": user " + userId + " is stopped");
15656                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15657            }
15658        }
15659
15660        /*
15661         * Prevent non-system code (defined here to be non-persistent
15662         * processes) from sending protected broadcasts.
15663         */
15664        int callingAppId = UserHandle.getAppId(callingUid);
15665        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15666            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15667            || callingAppId == Process.NFC_UID || callingUid == 0) {
15668            // Always okay.
15669        } else if (callerApp == null || !callerApp.persistent) {
15670            try {
15671                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15672                        intent.getAction())) {
15673                    String msg = "Permission Denial: not allowed to send broadcast "
15674                            + intent.getAction() + " from pid="
15675                            + callingPid + ", uid=" + callingUid;
15676                    Slog.w(TAG, msg);
15677                    throw new SecurityException(msg);
15678                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15679                    // Special case for compatibility: we don't want apps to send this,
15680                    // but historically it has not been protected and apps may be using it
15681                    // to poke their own app widget.  So, instead of making it protected,
15682                    // just limit it to the caller.
15683                    if (callerApp == null) {
15684                        String msg = "Permission Denial: not allowed to send broadcast "
15685                                + intent.getAction() + " from unknown caller.";
15686                        Slog.w(TAG, msg);
15687                        throw new SecurityException(msg);
15688                    } else if (intent.getComponent() != null) {
15689                        // They are good enough to send to an explicit component...  verify
15690                        // it is being sent to the calling app.
15691                        if (!intent.getComponent().getPackageName().equals(
15692                                callerApp.info.packageName)) {
15693                            String msg = "Permission Denial: not allowed to send broadcast "
15694                                    + intent.getAction() + " to "
15695                                    + intent.getComponent().getPackageName() + " from "
15696                                    + callerApp.info.packageName;
15697                            Slog.w(TAG, msg);
15698                            throw new SecurityException(msg);
15699                        }
15700                    } else {
15701                        // Limit broadcast to their own package.
15702                        intent.setPackage(callerApp.info.packageName);
15703                    }
15704                }
15705            } catch (RemoteException e) {
15706                Slog.w(TAG, "Remote exception", e);
15707                return ActivityManager.BROADCAST_SUCCESS;
15708            }
15709        }
15710
15711        final String action = intent.getAction();
15712        if (action != null) {
15713            switch (action) {
15714                case Intent.ACTION_UID_REMOVED:
15715                case Intent.ACTION_PACKAGE_REMOVED:
15716                case Intent.ACTION_PACKAGE_CHANGED:
15717                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15718                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15719                    // Handle special intents: if this broadcast is from the package
15720                    // manager about a package being removed, we need to remove all of
15721                    // its activities from the history stack.
15722                    if (checkComponentPermission(
15723                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15724                            callingPid, callingUid, -1, true)
15725                            != PackageManager.PERMISSION_GRANTED) {
15726                        String msg = "Permission Denial: " + intent.getAction()
15727                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15728                                + ", uid=" + callingUid + ")"
15729                                + " requires "
15730                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15731                        Slog.w(TAG, msg);
15732                        throw new SecurityException(msg);
15733                    }
15734                    switch (action) {
15735                        case Intent.ACTION_UID_REMOVED:
15736                            final Bundle intentExtras = intent.getExtras();
15737                            final int uid = intentExtras != null
15738                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15739                            if (uid >= 0) {
15740                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15741                                synchronized (bs) {
15742                                    bs.removeUidStatsLocked(uid);
15743                                }
15744                                mAppOpsService.uidRemoved(uid);
15745                            }
15746                            break;
15747                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15748                            // If resources are unavailable just force stop all those packages
15749                            // and flush the attribute cache as well.
15750                            String list[] =
15751                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15752                            if (list != null && list.length > 0) {
15753                                for (int i = 0; i < list.length; i++) {
15754                                    forceStopPackageLocked(list[i], -1, false, true, true,
15755                                            false, false, userId, "storage unmount");
15756                                }
15757                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15758                                sendPackageBroadcastLocked(
15759                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15760                                        userId);
15761                            }
15762                            break;
15763                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15764                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15765                            break;
15766                        case Intent.ACTION_PACKAGE_REMOVED:
15767                        case Intent.ACTION_PACKAGE_CHANGED:
15768                            Uri data = intent.getData();
15769                            String ssp;
15770                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15771                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15772                                boolean fullUninstall = removed &&
15773                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15774                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15775                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15776                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15777                                            false, true, true, false, fullUninstall, userId,
15778                                            removed ? "pkg removed" : "pkg changed");
15779                                }
15780                                if (removed) {
15781                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15782                                            new String[] {ssp}, userId);
15783                                    if (fullUninstall) {
15784                                        mAppOpsService.packageRemoved(
15785                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15786
15787                                        // Remove all permissions granted from/to this package
15788                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15789
15790                                        removeTasksByPackageNameLocked(ssp, userId);
15791                                    }
15792                                } else {
15793                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15794                                }
15795                            }
15796                            break;
15797                    }
15798                    break;
15799                case Intent.ACTION_PACKAGE_ADDED:
15800                    // Special case for adding a package: by default turn on compatibility mode.
15801                    Uri data = intent.getData();
15802                    String ssp;
15803                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15804                        final boolean replacing =
15805                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15806                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15807
15808                        if (replacing) {
15809                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15810                        }
15811                    }
15812                    break;
15813                case Intent.ACTION_TIMEZONE_CHANGED:
15814                    // If this is the time zone changed action, queue up a message that will reset
15815                    // the timezone of all currently running processes. This message will get
15816                    // queued up before the broadcast happens.
15817                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15818                    break;
15819                case Intent.ACTION_TIME_CHANGED:
15820                    // If the user set the time, let all running processes know.
15821                    final int is24Hour =
15822                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15823                                    : 0;
15824                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15825                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15826                    synchronized (stats) {
15827                        stats.noteCurrentTimeChangedLocked();
15828                    }
15829                    break;
15830                case Intent.ACTION_CLEAR_DNS_CACHE:
15831                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15832                    break;
15833                case Proxy.PROXY_CHANGE_ACTION:
15834                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15835                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15836                    break;
15837            }
15838        }
15839
15840        // Add to the sticky list if requested.
15841        if (sticky) {
15842            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15843                    callingPid, callingUid)
15844                    != PackageManager.PERMISSION_GRANTED) {
15845                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15846                        + callingPid + ", uid=" + callingUid
15847                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15848                Slog.w(TAG, msg);
15849                throw new SecurityException(msg);
15850            }
15851            if (requiredPermission != null) {
15852                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15853                        + " and enforce permission " + requiredPermission);
15854                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15855            }
15856            if (intent.getComponent() != null) {
15857                throw new SecurityException(
15858                        "Sticky broadcasts can't target a specific component");
15859            }
15860            // We use userId directly here, since the "all" target is maintained
15861            // as a separate set of sticky broadcasts.
15862            if (userId != UserHandle.USER_ALL) {
15863                // But first, if this is not a broadcast to all users, then
15864                // make sure it doesn't conflict with an existing broadcast to
15865                // all users.
15866                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15867                        UserHandle.USER_ALL);
15868                if (stickies != null) {
15869                    ArrayList<Intent> list = stickies.get(intent.getAction());
15870                    if (list != null) {
15871                        int N = list.size();
15872                        int i;
15873                        for (i=0; i<N; i++) {
15874                            if (intent.filterEquals(list.get(i))) {
15875                                throw new IllegalArgumentException(
15876                                        "Sticky broadcast " + intent + " for user "
15877                                        + userId + " conflicts with existing global broadcast");
15878                            }
15879                        }
15880                    }
15881                }
15882            }
15883            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15884            if (stickies == null) {
15885                stickies = new ArrayMap<String, ArrayList<Intent>>();
15886                mStickyBroadcasts.put(userId, stickies);
15887            }
15888            ArrayList<Intent> list = stickies.get(intent.getAction());
15889            if (list == null) {
15890                list = new ArrayList<Intent>();
15891                stickies.put(intent.getAction(), list);
15892            }
15893            int N = list.size();
15894            int i;
15895            for (i=0; i<N; i++) {
15896                if (intent.filterEquals(list.get(i))) {
15897                    // This sticky already exists, replace it.
15898                    list.set(i, new Intent(intent));
15899                    break;
15900                }
15901            }
15902            if (i >= N) {
15903                list.add(new Intent(intent));
15904            }
15905        }
15906
15907        int[] users;
15908        if (userId == UserHandle.USER_ALL) {
15909            // Caller wants broadcast to go to all started users.
15910            users = mStartedUserArray;
15911        } else {
15912            // Caller wants broadcast to go to one specific user.
15913            users = new int[] {userId};
15914        }
15915
15916        // Figure out who all will receive this broadcast.
15917        List receivers = null;
15918        List<BroadcastFilter> registeredReceivers = null;
15919        // Need to resolve the intent to interested receivers...
15920        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15921                 == 0) {
15922            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15923        }
15924        if (intent.getComponent() == null) {
15925            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15926                // Query one target user at a time, excluding shell-restricted users
15927                UserManagerService ums = getUserManagerLocked();
15928                for (int i = 0; i < users.length; i++) {
15929                    if (ums.hasUserRestriction(
15930                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15931                        continue;
15932                    }
15933                    List<BroadcastFilter> registeredReceiversForUser =
15934                            mReceiverResolver.queryIntent(intent,
15935                                    resolvedType, false, users[i]);
15936                    if (registeredReceivers == null) {
15937                        registeredReceivers = registeredReceiversForUser;
15938                    } else if (registeredReceiversForUser != null) {
15939                        registeredReceivers.addAll(registeredReceiversForUser);
15940                    }
15941                }
15942            } else {
15943                registeredReceivers = mReceiverResolver.queryIntent(intent,
15944                        resolvedType, false, userId);
15945            }
15946        }
15947
15948        final boolean replacePending =
15949                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15950
15951        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15952                + " replacePending=" + replacePending);
15953
15954        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15955        if (!ordered && NR > 0) {
15956            // If we are not serializing this broadcast, then send the
15957            // registered receivers separately so they don't wait for the
15958            // components to be launched.
15959            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15960            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15961                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15962                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15963                    ordered, sticky, false, userId);
15964            if (DEBUG_BROADCAST) Slog.v(
15965                    TAG, "Enqueueing parallel broadcast " + r);
15966            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15967            if (!replaced) {
15968                queue.enqueueParallelBroadcastLocked(r);
15969                queue.scheduleBroadcastsLocked();
15970            }
15971            registeredReceivers = null;
15972            NR = 0;
15973        }
15974
15975        // Merge into one list.
15976        int ir = 0;
15977        if (receivers != null) {
15978            // A special case for PACKAGE_ADDED: do not allow the package
15979            // being added to see this broadcast.  This prevents them from
15980            // using this as a back door to get run as soon as they are
15981            // installed.  Maybe in the future we want to have a special install
15982            // broadcast or such for apps, but we'd like to deliberately make
15983            // this decision.
15984            String skipPackages[] = null;
15985            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15986                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15987                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15988                Uri data = intent.getData();
15989                if (data != null) {
15990                    String pkgName = data.getSchemeSpecificPart();
15991                    if (pkgName != null) {
15992                        skipPackages = new String[] { pkgName };
15993                    }
15994                }
15995            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15996                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15997            }
15998            if (skipPackages != null && (skipPackages.length > 0)) {
15999                for (String skipPackage : skipPackages) {
16000                    if (skipPackage != null) {
16001                        int NT = receivers.size();
16002                        for (int it=0; it<NT; it++) {
16003                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16004                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16005                                receivers.remove(it);
16006                                it--;
16007                                NT--;
16008                            }
16009                        }
16010                    }
16011                }
16012            }
16013
16014            int NT = receivers != null ? receivers.size() : 0;
16015            int it = 0;
16016            ResolveInfo curt = null;
16017            BroadcastFilter curr = null;
16018            while (it < NT && ir < NR) {
16019                if (curt == null) {
16020                    curt = (ResolveInfo)receivers.get(it);
16021                }
16022                if (curr == null) {
16023                    curr = registeredReceivers.get(ir);
16024                }
16025                if (curr.getPriority() >= curt.priority) {
16026                    // Insert this broadcast record into the final list.
16027                    receivers.add(it, curr);
16028                    ir++;
16029                    curr = null;
16030                    it++;
16031                    NT++;
16032                } else {
16033                    // Skip to the next ResolveInfo in the final list.
16034                    it++;
16035                    curt = null;
16036                }
16037            }
16038        }
16039        while (ir < NR) {
16040            if (receivers == null) {
16041                receivers = new ArrayList();
16042            }
16043            receivers.add(registeredReceivers.get(ir));
16044            ir++;
16045        }
16046
16047        if ((receivers != null && receivers.size() > 0)
16048                || resultTo != null) {
16049            BroadcastQueue queue = broadcastQueueForIntent(intent);
16050            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16051                    callerPackage, callingPid, callingUid, resolvedType,
16052                    requiredPermission, appOp, receivers, resultTo, resultCode,
16053                    resultData, map, ordered, sticky, false, userId);
16054            if (DEBUG_BROADCAST) Slog.v(
16055                    TAG, "Enqueueing ordered broadcast " + r
16056                    + ": prev had " + queue.mOrderedBroadcasts.size());
16057            if (DEBUG_BROADCAST) {
16058                int seq = r.intent.getIntExtra("seq", -1);
16059                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16060            }
16061            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16062            if (!replaced) {
16063                queue.enqueueOrderedBroadcastLocked(r);
16064                queue.scheduleBroadcastsLocked();
16065            }
16066        }
16067
16068        return ActivityManager.BROADCAST_SUCCESS;
16069    }
16070
16071    final Intent verifyBroadcastLocked(Intent intent) {
16072        // Refuse possible leaked file descriptors
16073        if (intent != null && intent.hasFileDescriptors() == true) {
16074            throw new IllegalArgumentException("File descriptors passed in Intent");
16075        }
16076
16077        int flags = intent.getFlags();
16078
16079        if (!mProcessesReady) {
16080            // if the caller really truly claims to know what they're doing, go
16081            // ahead and allow the broadcast without launching any receivers
16082            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16083                intent = new Intent(intent);
16084                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16085            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16086                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16087                        + " before boot completion");
16088                throw new IllegalStateException("Cannot broadcast before boot completed");
16089            }
16090        }
16091
16092        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16093            throw new IllegalArgumentException(
16094                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16095        }
16096
16097        return intent;
16098    }
16099
16100    public final int broadcastIntent(IApplicationThread caller,
16101            Intent intent, String resolvedType, IIntentReceiver resultTo,
16102            int resultCode, String resultData, Bundle map,
16103            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16104        enforceNotIsolatedCaller("broadcastIntent");
16105        synchronized(this) {
16106            intent = verifyBroadcastLocked(intent);
16107
16108            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16109            final int callingPid = Binder.getCallingPid();
16110            final int callingUid = Binder.getCallingUid();
16111            final long origId = Binder.clearCallingIdentity();
16112            int res = broadcastIntentLocked(callerApp,
16113                    callerApp != null ? callerApp.info.packageName : null,
16114                    intent, resolvedType, resultTo,
16115                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16116                    callingPid, callingUid, userId);
16117            Binder.restoreCallingIdentity(origId);
16118            return res;
16119        }
16120    }
16121
16122    int broadcastIntentInPackage(String packageName, int uid,
16123            Intent intent, String resolvedType, IIntentReceiver resultTo,
16124            int resultCode, String resultData, Bundle map,
16125            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16126        synchronized(this) {
16127            intent = verifyBroadcastLocked(intent);
16128
16129            final long origId = Binder.clearCallingIdentity();
16130            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16131                    resultTo, resultCode, resultData, map, requiredPermission,
16132                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16133            Binder.restoreCallingIdentity(origId);
16134            return res;
16135        }
16136    }
16137
16138    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16139        // Refuse possible leaked file descriptors
16140        if (intent != null && intent.hasFileDescriptors() == true) {
16141            throw new IllegalArgumentException("File descriptors passed in Intent");
16142        }
16143
16144        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16145                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16146
16147        synchronized(this) {
16148            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16149                    != PackageManager.PERMISSION_GRANTED) {
16150                String msg = "Permission Denial: unbroadcastIntent() from pid="
16151                        + Binder.getCallingPid()
16152                        + ", uid=" + Binder.getCallingUid()
16153                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16154                Slog.w(TAG, msg);
16155                throw new SecurityException(msg);
16156            }
16157            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16158            if (stickies != null) {
16159                ArrayList<Intent> list = stickies.get(intent.getAction());
16160                if (list != null) {
16161                    int N = list.size();
16162                    int i;
16163                    for (i=0; i<N; i++) {
16164                        if (intent.filterEquals(list.get(i))) {
16165                            list.remove(i);
16166                            break;
16167                        }
16168                    }
16169                    if (list.size() <= 0) {
16170                        stickies.remove(intent.getAction());
16171                    }
16172                }
16173                if (stickies.size() <= 0) {
16174                    mStickyBroadcasts.remove(userId);
16175                }
16176            }
16177        }
16178    }
16179
16180    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16181            String resultData, Bundle resultExtras, boolean resultAbort) {
16182        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16183        if (r == null) {
16184            Slog.w(TAG, "finishReceiver called but not found on queue");
16185            return false;
16186        }
16187
16188        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16189    }
16190
16191    void backgroundServicesFinishedLocked(int userId) {
16192        for (BroadcastQueue queue : mBroadcastQueues) {
16193            queue.backgroundServicesFinishedLocked(userId);
16194        }
16195    }
16196
16197    public void finishReceiver(IBinder who, int resultCode, String resultData,
16198            Bundle resultExtras, boolean resultAbort) {
16199        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16200
16201        // Refuse possible leaked file descriptors
16202        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16203            throw new IllegalArgumentException("File descriptors passed in Bundle");
16204        }
16205
16206        final long origId = Binder.clearCallingIdentity();
16207        try {
16208            boolean doNext = false;
16209            BroadcastRecord r;
16210
16211            synchronized(this) {
16212                r = broadcastRecordForReceiverLocked(who);
16213                if (r != null) {
16214                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16215                        resultData, resultExtras, resultAbort, true);
16216                }
16217            }
16218
16219            if (doNext) {
16220                r.queue.processNextBroadcast(false);
16221            }
16222            trimApplications();
16223        } finally {
16224            Binder.restoreCallingIdentity(origId);
16225        }
16226    }
16227
16228    // =========================================================
16229    // INSTRUMENTATION
16230    // =========================================================
16231
16232    public boolean startInstrumentation(ComponentName className,
16233            String profileFile, int flags, Bundle arguments,
16234            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16235            int userId, String abiOverride) {
16236        enforceNotIsolatedCaller("startInstrumentation");
16237        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16238                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16239        // Refuse possible leaked file descriptors
16240        if (arguments != null && arguments.hasFileDescriptors()) {
16241            throw new IllegalArgumentException("File descriptors passed in Bundle");
16242        }
16243
16244        synchronized(this) {
16245            InstrumentationInfo ii = null;
16246            ApplicationInfo ai = null;
16247            try {
16248                ii = mContext.getPackageManager().getInstrumentationInfo(
16249                    className, STOCK_PM_FLAGS);
16250                ai = AppGlobals.getPackageManager().getApplicationInfo(
16251                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16252            } catch (PackageManager.NameNotFoundException e) {
16253            } catch (RemoteException e) {
16254            }
16255            if (ii == null) {
16256                reportStartInstrumentationFailure(watcher, className,
16257                        "Unable to find instrumentation info for: " + className);
16258                return false;
16259            }
16260            if (ai == null) {
16261                reportStartInstrumentationFailure(watcher, className,
16262                        "Unable to find instrumentation target package: " + ii.targetPackage);
16263                return false;
16264            }
16265
16266            int match = mContext.getPackageManager().checkSignatures(
16267                    ii.targetPackage, ii.packageName);
16268            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16269                String msg = "Permission Denial: starting instrumentation "
16270                        + className + " from pid="
16271                        + Binder.getCallingPid()
16272                        + ", uid=" + Binder.getCallingPid()
16273                        + " not allowed because package " + ii.packageName
16274                        + " does not have a signature matching the target "
16275                        + ii.targetPackage;
16276                reportStartInstrumentationFailure(watcher, className, msg);
16277                throw new SecurityException(msg);
16278            }
16279
16280            final long origId = Binder.clearCallingIdentity();
16281            // Instrumentation can kill and relaunch even persistent processes
16282            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16283                    "start instr");
16284            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16285            app.instrumentationClass = className;
16286            app.instrumentationInfo = ai;
16287            app.instrumentationProfileFile = profileFile;
16288            app.instrumentationArguments = arguments;
16289            app.instrumentationWatcher = watcher;
16290            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16291            app.instrumentationResultClass = className;
16292            Binder.restoreCallingIdentity(origId);
16293        }
16294
16295        return true;
16296    }
16297
16298    /**
16299     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16300     * error to the logs, but if somebody is watching, send the report there too.  This enables
16301     * the "am" command to report errors with more information.
16302     *
16303     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16304     * @param cn The component name of the instrumentation.
16305     * @param report The error report.
16306     */
16307    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16308            ComponentName cn, String report) {
16309        Slog.w(TAG, report);
16310        try {
16311            if (watcher != null) {
16312                Bundle results = new Bundle();
16313                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16314                results.putString("Error", report);
16315                watcher.instrumentationStatus(cn, -1, results);
16316            }
16317        } catch (RemoteException e) {
16318            Slog.w(TAG, e);
16319        }
16320    }
16321
16322    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16323        if (app.instrumentationWatcher != null) {
16324            try {
16325                // NOTE:  IInstrumentationWatcher *must* be oneway here
16326                app.instrumentationWatcher.instrumentationFinished(
16327                    app.instrumentationClass,
16328                    resultCode,
16329                    results);
16330            } catch (RemoteException e) {
16331            }
16332        }
16333        if (app.instrumentationUiAutomationConnection != null) {
16334            try {
16335                app.instrumentationUiAutomationConnection.shutdown();
16336            } catch (RemoteException re) {
16337                /* ignore */
16338            }
16339            // Only a UiAutomation can set this flag and now that
16340            // it is finished we make sure it is reset to its default.
16341            mUserIsMonkey = false;
16342        }
16343        app.instrumentationWatcher = null;
16344        app.instrumentationUiAutomationConnection = null;
16345        app.instrumentationClass = null;
16346        app.instrumentationInfo = null;
16347        app.instrumentationProfileFile = null;
16348        app.instrumentationArguments = null;
16349
16350        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16351                "finished inst");
16352    }
16353
16354    public void finishInstrumentation(IApplicationThread target,
16355            int resultCode, Bundle results) {
16356        int userId = UserHandle.getCallingUserId();
16357        // Refuse possible leaked file descriptors
16358        if (results != null && results.hasFileDescriptors()) {
16359            throw new IllegalArgumentException("File descriptors passed in Intent");
16360        }
16361
16362        synchronized(this) {
16363            ProcessRecord app = getRecordForAppLocked(target);
16364            if (app == null) {
16365                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16366                return;
16367            }
16368            final long origId = Binder.clearCallingIdentity();
16369            finishInstrumentationLocked(app, resultCode, results);
16370            Binder.restoreCallingIdentity(origId);
16371        }
16372    }
16373
16374    // =========================================================
16375    // CONFIGURATION
16376    // =========================================================
16377
16378    public ConfigurationInfo getDeviceConfigurationInfo() {
16379        ConfigurationInfo config = new ConfigurationInfo();
16380        synchronized (this) {
16381            config.reqTouchScreen = mConfiguration.touchscreen;
16382            config.reqKeyboardType = mConfiguration.keyboard;
16383            config.reqNavigation = mConfiguration.navigation;
16384            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16385                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16386                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16387            }
16388            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16389                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16390                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16391            }
16392            config.reqGlEsVersion = GL_ES_VERSION;
16393        }
16394        return config;
16395    }
16396
16397    ActivityStack getFocusedStack() {
16398        return mStackSupervisor.getFocusedStack();
16399    }
16400
16401    public Configuration getConfiguration() {
16402        Configuration ci;
16403        synchronized(this) {
16404            ci = new Configuration(mConfiguration);
16405        }
16406        return ci;
16407    }
16408
16409    public void updatePersistentConfiguration(Configuration values) {
16410        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16411                "updateConfiguration()");
16412        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16413                "updateConfiguration()");
16414        if (values == null) {
16415            throw new NullPointerException("Configuration must not be null");
16416        }
16417
16418        synchronized(this) {
16419            final long origId = Binder.clearCallingIdentity();
16420            updateConfigurationLocked(values, null, true, false);
16421            Binder.restoreCallingIdentity(origId);
16422        }
16423    }
16424
16425    public void updateConfiguration(Configuration values) {
16426        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16427                "updateConfiguration()");
16428
16429        synchronized(this) {
16430            if (values == null && mWindowManager != null) {
16431                // sentinel: fetch the current configuration from the window manager
16432                values = mWindowManager.computeNewConfiguration();
16433            }
16434
16435            if (mWindowManager != null) {
16436                mProcessList.applyDisplaySize(mWindowManager);
16437            }
16438
16439            final long origId = Binder.clearCallingIdentity();
16440            if (values != null) {
16441                Settings.System.clearConfiguration(values);
16442            }
16443            updateConfigurationLocked(values, null, false, false);
16444            Binder.restoreCallingIdentity(origId);
16445        }
16446    }
16447
16448    /**
16449     * Do either or both things: (1) change the current configuration, and (2)
16450     * make sure the given activity is running with the (now) current
16451     * configuration.  Returns true if the activity has been left running, or
16452     * false if <var>starting</var> is being destroyed to match the new
16453     * configuration.
16454     * @param persistent TODO
16455     */
16456    boolean updateConfigurationLocked(Configuration values,
16457            ActivityRecord starting, boolean persistent, boolean initLocale) {
16458        int changes = 0;
16459
16460        if (values != null) {
16461            Configuration newConfig = new Configuration(mConfiguration);
16462            changes = newConfig.updateFrom(values);
16463            if (changes != 0) {
16464                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16465                    Slog.i(TAG, "Updating configuration to: " + values);
16466                }
16467
16468                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16469
16470                if (values.locale != null && !initLocale) {
16471                    saveLocaleLocked(values.locale,
16472                                     !values.locale.equals(mConfiguration.locale),
16473                                     values.userSetLocale);
16474                }
16475
16476                mConfigurationSeq++;
16477                if (mConfigurationSeq <= 0) {
16478                    mConfigurationSeq = 1;
16479                }
16480                newConfig.seq = mConfigurationSeq;
16481                mConfiguration = newConfig;
16482                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16483                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16484                //mUsageStatsService.noteStartConfig(newConfig);
16485
16486                final Configuration configCopy = new Configuration(mConfiguration);
16487
16488                // TODO: If our config changes, should we auto dismiss any currently
16489                // showing dialogs?
16490                mShowDialogs = shouldShowDialogs(newConfig);
16491
16492                AttributeCache ac = AttributeCache.instance();
16493                if (ac != null) {
16494                    ac.updateConfiguration(configCopy);
16495                }
16496
16497                // Make sure all resources in our process are updated
16498                // right now, so that anyone who is going to retrieve
16499                // resource values after we return will be sure to get
16500                // the new ones.  This is especially important during
16501                // boot, where the first config change needs to guarantee
16502                // all resources have that config before following boot
16503                // code is executed.
16504                mSystemThread.applyConfigurationToResources(configCopy);
16505
16506                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16507                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16508                    msg.obj = new Configuration(configCopy);
16509                    mHandler.sendMessage(msg);
16510                }
16511
16512                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16513                    ProcessRecord app = mLruProcesses.get(i);
16514                    try {
16515                        if (app.thread != null) {
16516                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16517                                    + app.processName + " new config " + mConfiguration);
16518                            app.thread.scheduleConfigurationChanged(configCopy);
16519                        }
16520                    } catch (Exception e) {
16521                    }
16522                }
16523                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16524                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16525                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16526                        | Intent.FLAG_RECEIVER_FOREGROUND);
16527                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16528                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16529                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16530                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16531                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16532                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16533                    broadcastIntentLocked(null, null, intent,
16534                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16535                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16536                }
16537            }
16538        }
16539
16540        boolean kept = true;
16541        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16542        // mainStack is null during startup.
16543        if (mainStack != null) {
16544            if (changes != 0 && starting == null) {
16545                // If the configuration changed, and the caller is not already
16546                // in the process of starting an activity, then find the top
16547                // activity to check if its configuration needs to change.
16548                starting = mainStack.topRunningActivityLocked(null);
16549            }
16550
16551            if (starting != null) {
16552                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16553                // And we need to make sure at this point that all other activities
16554                // are made visible with the correct configuration.
16555                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16556            }
16557        }
16558
16559        if (values != null && mWindowManager != null) {
16560            mWindowManager.setNewConfiguration(mConfiguration);
16561        }
16562
16563        return kept;
16564    }
16565
16566    /**
16567     * Decide based on the configuration whether we should shouw the ANR,
16568     * crash, etc dialogs.  The idea is that if there is no affordnace to
16569     * press the on-screen buttons, we shouldn't show the dialog.
16570     *
16571     * A thought: SystemUI might also want to get told about this, the Power
16572     * dialog / global actions also might want different behaviors.
16573     */
16574    private static final boolean shouldShowDialogs(Configuration config) {
16575        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16576                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16577    }
16578
16579    /**
16580     * Save the locale.  You must be inside a synchronized (this) block.
16581     */
16582    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16583        if(isDiff) {
16584            SystemProperties.set("user.language", l.getLanguage());
16585            SystemProperties.set("user.region", l.getCountry());
16586        }
16587
16588        if(isPersist) {
16589            SystemProperties.set("persist.sys.language", l.getLanguage());
16590            SystemProperties.set("persist.sys.country", l.getCountry());
16591            SystemProperties.set("persist.sys.localevar", l.getVariant());
16592
16593            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16594        }
16595    }
16596
16597    @Override
16598    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16599        synchronized (this) {
16600            ActivityRecord srec = ActivityRecord.forToken(token);
16601            if (srec.task != null && srec.task.stack != null) {
16602                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16603            }
16604        }
16605        return false;
16606    }
16607
16608    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16609            Intent resultData) {
16610
16611        synchronized (this) {
16612            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16613            if (stack != null) {
16614                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16615            }
16616            return false;
16617        }
16618    }
16619
16620    public int getLaunchedFromUid(IBinder activityToken) {
16621        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16622        if (srec == null) {
16623            return -1;
16624        }
16625        return srec.launchedFromUid;
16626    }
16627
16628    public String getLaunchedFromPackage(IBinder activityToken) {
16629        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16630        if (srec == null) {
16631            return null;
16632        }
16633        return srec.launchedFromPackage;
16634    }
16635
16636    // =========================================================
16637    // LIFETIME MANAGEMENT
16638    // =========================================================
16639
16640    // Returns which broadcast queue the app is the current [or imminent] receiver
16641    // on, or 'null' if the app is not an active broadcast recipient.
16642    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16643        BroadcastRecord r = app.curReceiver;
16644        if (r != null) {
16645            return r.queue;
16646        }
16647
16648        // It's not the current receiver, but it might be starting up to become one
16649        synchronized (this) {
16650            for (BroadcastQueue queue : mBroadcastQueues) {
16651                r = queue.mPendingBroadcast;
16652                if (r != null && r.curApp == app) {
16653                    // found it; report which queue it's in
16654                    return queue;
16655                }
16656            }
16657        }
16658
16659        return null;
16660    }
16661
16662    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16663            boolean doingAll, long now) {
16664        if (mAdjSeq == app.adjSeq) {
16665            // This adjustment has already been computed.
16666            return app.curRawAdj;
16667        }
16668
16669        if (app.thread == null) {
16670            app.adjSeq = mAdjSeq;
16671            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16672            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16673            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16674        }
16675
16676        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16677        app.adjSource = null;
16678        app.adjTarget = null;
16679        app.empty = false;
16680        app.cached = false;
16681
16682        final int activitiesSize = app.activities.size();
16683
16684        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16685            // The max adjustment doesn't allow this app to be anything
16686            // below foreground, so it is not worth doing work for it.
16687            app.adjType = "fixed";
16688            app.adjSeq = mAdjSeq;
16689            app.curRawAdj = app.maxAdj;
16690            app.foregroundActivities = false;
16691            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16692            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16693            // System processes can do UI, and when they do we want to have
16694            // them trim their memory after the user leaves the UI.  To
16695            // facilitate this, here we need to determine whether or not it
16696            // is currently showing UI.
16697            app.systemNoUi = true;
16698            if (app == TOP_APP) {
16699                app.systemNoUi = false;
16700            } else if (activitiesSize > 0) {
16701                for (int j = 0; j < activitiesSize; j++) {
16702                    final ActivityRecord r = app.activities.get(j);
16703                    if (r.visible) {
16704                        app.systemNoUi = false;
16705                    }
16706                }
16707            }
16708            if (!app.systemNoUi) {
16709                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16710            }
16711            return (app.curAdj=app.maxAdj);
16712        }
16713
16714        app.systemNoUi = false;
16715
16716        // Determine the importance of the process, starting with most
16717        // important to least, and assign an appropriate OOM adjustment.
16718        int adj;
16719        int schedGroup;
16720        int procState;
16721        boolean foregroundActivities = false;
16722        BroadcastQueue queue;
16723        if (app == TOP_APP) {
16724            // The last app on the list is the foreground app.
16725            adj = ProcessList.FOREGROUND_APP_ADJ;
16726            schedGroup = Process.THREAD_GROUP_DEFAULT;
16727            app.adjType = "top-activity";
16728            foregroundActivities = true;
16729            procState = ActivityManager.PROCESS_STATE_TOP;
16730        } else if (app.instrumentationClass != null) {
16731            // Don't want to kill running instrumentation.
16732            adj = ProcessList.FOREGROUND_APP_ADJ;
16733            schedGroup = Process.THREAD_GROUP_DEFAULT;
16734            app.adjType = "instrumentation";
16735            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16736        } else if ((queue = isReceivingBroadcast(app)) != null) {
16737            // An app that is currently receiving a broadcast also
16738            // counts as being in the foreground for OOM killer purposes.
16739            // It's placed in a sched group based on the nature of the
16740            // broadcast as reflected by which queue it's active in.
16741            adj = ProcessList.FOREGROUND_APP_ADJ;
16742            schedGroup = (queue == mFgBroadcastQueue)
16743                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16744            app.adjType = "broadcast";
16745            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16746        } else if (app.executingServices.size() > 0) {
16747            // An app that is currently executing a service callback also
16748            // counts as being in the foreground.
16749            adj = ProcessList.FOREGROUND_APP_ADJ;
16750            schedGroup = app.execServicesFg ?
16751                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16752            app.adjType = "exec-service";
16753            procState = ActivityManager.PROCESS_STATE_SERVICE;
16754            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16755        } else {
16756            // As far as we know the process is empty.  We may change our mind later.
16757            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16758            // At this point we don't actually know the adjustment.  Use the cached adj
16759            // value that the caller wants us to.
16760            adj = cachedAdj;
16761            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16762            app.cached = true;
16763            app.empty = true;
16764            app.adjType = "cch-empty";
16765        }
16766
16767        // Examine all activities if not already foreground.
16768        if (!foregroundActivities && activitiesSize > 0) {
16769            for (int j = 0; j < activitiesSize; j++) {
16770                final ActivityRecord r = app.activities.get(j);
16771                if (r.app != app) {
16772                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16773                            + app + "?!?");
16774                    continue;
16775                }
16776                if (r.visible) {
16777                    // App has a visible activity; only upgrade adjustment.
16778                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16779                        adj = ProcessList.VISIBLE_APP_ADJ;
16780                        app.adjType = "visible";
16781                    }
16782                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16783                        procState = ActivityManager.PROCESS_STATE_TOP;
16784                    }
16785                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16786                    app.cached = false;
16787                    app.empty = false;
16788                    foregroundActivities = true;
16789                    break;
16790                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16791                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16792                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16793                        app.adjType = "pausing";
16794                    }
16795                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16796                        procState = ActivityManager.PROCESS_STATE_TOP;
16797                    }
16798                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16799                    app.cached = false;
16800                    app.empty = false;
16801                    foregroundActivities = true;
16802                } else if (r.state == ActivityState.STOPPING) {
16803                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16804                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16805                        app.adjType = "stopping";
16806                    }
16807                    // For the process state, we will at this point consider the
16808                    // process to be cached.  It will be cached either as an activity
16809                    // or empty depending on whether the activity is finishing.  We do
16810                    // this so that we can treat the process as cached for purposes of
16811                    // memory trimming (determing current memory level, trim command to
16812                    // send to process) since there can be an arbitrary number of stopping
16813                    // processes and they should soon all go into the cached state.
16814                    if (!r.finishing) {
16815                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16816                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16817                        }
16818                    }
16819                    app.cached = false;
16820                    app.empty = false;
16821                    foregroundActivities = true;
16822                } else {
16823                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16824                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16825                        app.adjType = "cch-act";
16826                    }
16827                }
16828            }
16829        }
16830
16831        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16832            if (app.foregroundServices) {
16833                // The user is aware of this app, so make it visible.
16834                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16835                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16836                app.cached = false;
16837                app.adjType = "fg-service";
16838                schedGroup = Process.THREAD_GROUP_DEFAULT;
16839            } else if (app.forcingToForeground != null) {
16840                // The user is aware of this app, so make it visible.
16841                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16842                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16843                app.cached = false;
16844                app.adjType = "force-fg";
16845                app.adjSource = app.forcingToForeground;
16846                schedGroup = Process.THREAD_GROUP_DEFAULT;
16847            }
16848        }
16849
16850        if (app == mHeavyWeightProcess) {
16851            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16852                // We don't want to kill the current heavy-weight process.
16853                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16854                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16855                app.cached = false;
16856                app.adjType = "heavy";
16857            }
16858            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16859                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16860            }
16861        }
16862
16863        if (app == mHomeProcess) {
16864            if (adj > ProcessList.HOME_APP_ADJ) {
16865                // This process is hosting what we currently consider to be the
16866                // home app, so we don't want to let it go into the background.
16867                adj = ProcessList.HOME_APP_ADJ;
16868                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16869                app.cached = false;
16870                app.adjType = "home";
16871            }
16872            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16873                procState = ActivityManager.PROCESS_STATE_HOME;
16874            }
16875        }
16876
16877        if (app == mPreviousProcess && app.activities.size() > 0) {
16878            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16879                // This was the previous process that showed UI to the user.
16880                // We want to try to keep it around more aggressively, to give
16881                // a good experience around switching between two apps.
16882                adj = ProcessList.PREVIOUS_APP_ADJ;
16883                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16884                app.cached = false;
16885                app.adjType = "previous";
16886            }
16887            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16888                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16889            }
16890        }
16891
16892        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16893                + " reason=" + app.adjType);
16894
16895        // By default, we use the computed adjustment.  It may be changed if
16896        // there are applications dependent on our services or providers, but
16897        // this gives us a baseline and makes sure we don't get into an
16898        // infinite recursion.
16899        app.adjSeq = mAdjSeq;
16900        app.curRawAdj = adj;
16901        app.hasStartedServices = false;
16902
16903        if (mBackupTarget != null && app == mBackupTarget.app) {
16904            // If possible we want to avoid killing apps while they're being backed up
16905            if (adj > ProcessList.BACKUP_APP_ADJ) {
16906                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16907                adj = ProcessList.BACKUP_APP_ADJ;
16908                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16909                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16910                }
16911                app.adjType = "backup";
16912                app.cached = false;
16913            }
16914            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16915                procState = ActivityManager.PROCESS_STATE_BACKUP;
16916            }
16917        }
16918
16919        boolean mayBeTop = false;
16920
16921        for (int is = app.services.size()-1;
16922                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16923                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16924                        || procState > ActivityManager.PROCESS_STATE_TOP);
16925                is--) {
16926            ServiceRecord s = app.services.valueAt(is);
16927            if (s.startRequested) {
16928                app.hasStartedServices = true;
16929                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16930                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16931                }
16932                if (app.hasShownUi && app != mHomeProcess) {
16933                    // If this process has shown some UI, let it immediately
16934                    // go to the LRU list because it may be pretty heavy with
16935                    // UI stuff.  We'll tag it with a label just to help
16936                    // debug and understand what is going on.
16937                    if (adj > ProcessList.SERVICE_ADJ) {
16938                        app.adjType = "cch-started-ui-services";
16939                    }
16940                } else {
16941                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16942                        // This service has seen some activity within
16943                        // recent memory, so we will keep its process ahead
16944                        // of the background processes.
16945                        if (adj > ProcessList.SERVICE_ADJ) {
16946                            adj = ProcessList.SERVICE_ADJ;
16947                            app.adjType = "started-services";
16948                            app.cached = false;
16949                        }
16950                    }
16951                    // If we have let the service slide into the background
16952                    // state, still have some text describing what it is doing
16953                    // even though the service no longer has an impact.
16954                    if (adj > ProcessList.SERVICE_ADJ) {
16955                        app.adjType = "cch-started-services";
16956                    }
16957                }
16958            }
16959            for (int conni = s.connections.size()-1;
16960                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16961                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16962                            || procState > ActivityManager.PROCESS_STATE_TOP);
16963                    conni--) {
16964                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16965                for (int i = 0;
16966                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16967                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16968                                || procState > ActivityManager.PROCESS_STATE_TOP);
16969                        i++) {
16970                    // XXX should compute this based on the max of
16971                    // all connected clients.
16972                    ConnectionRecord cr = clist.get(i);
16973                    if (cr.binding.client == app) {
16974                        // Binding to ourself is not interesting.
16975                        continue;
16976                    }
16977                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16978                        ProcessRecord client = cr.binding.client;
16979                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16980                                TOP_APP, doingAll, now);
16981                        int clientProcState = client.curProcState;
16982                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16983                            // If the other app is cached for any reason, for purposes here
16984                            // we are going to consider it empty.  The specific cached state
16985                            // doesn't propagate except under certain conditions.
16986                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16987                        }
16988                        String adjType = null;
16989                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16990                            // Not doing bind OOM management, so treat
16991                            // this guy more like a started service.
16992                            if (app.hasShownUi && app != mHomeProcess) {
16993                                // If this process has shown some UI, let it immediately
16994                                // go to the LRU list because it may be pretty heavy with
16995                                // UI stuff.  We'll tag it with a label just to help
16996                                // debug and understand what is going on.
16997                                if (adj > clientAdj) {
16998                                    adjType = "cch-bound-ui-services";
16999                                }
17000                                app.cached = false;
17001                                clientAdj = adj;
17002                                clientProcState = procState;
17003                            } else {
17004                                if (now >= (s.lastActivity
17005                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17006                                    // This service has not seen activity within
17007                                    // recent memory, so allow it to drop to the
17008                                    // LRU list if there is no other reason to keep
17009                                    // it around.  We'll also tag it with a label just
17010                                    // to help debug and undertand what is going on.
17011                                    if (adj > clientAdj) {
17012                                        adjType = "cch-bound-services";
17013                                    }
17014                                    clientAdj = adj;
17015                                }
17016                            }
17017                        }
17018                        if (adj > clientAdj) {
17019                            // If this process has recently shown UI, and
17020                            // the process that is binding to it is less
17021                            // important than being visible, then we don't
17022                            // care about the binding as much as we care
17023                            // about letting this process get into the LRU
17024                            // list to be killed and restarted if needed for
17025                            // memory.
17026                            if (app.hasShownUi && app != mHomeProcess
17027                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17028                                adjType = "cch-bound-ui-services";
17029                            } else {
17030                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17031                                        |Context.BIND_IMPORTANT)) != 0) {
17032                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17033                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17034                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17035                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17036                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17037                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17038                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17039                                    adj = clientAdj;
17040                                } else {
17041                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17042                                        adj = ProcessList.VISIBLE_APP_ADJ;
17043                                    }
17044                                }
17045                                if (!client.cached) {
17046                                    app.cached = false;
17047                                }
17048                                adjType = "service";
17049                            }
17050                        }
17051                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17052                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17053                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17054                            }
17055                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17056                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17057                                    // Special handling of clients who are in the top state.
17058                                    // We *may* want to consider this process to be in the
17059                                    // top state as well, but only if there is not another
17060                                    // reason for it to be running.  Being on the top is a
17061                                    // special state, meaning you are specifically running
17062                                    // for the current top app.  If the process is already
17063                                    // running in the background for some other reason, it
17064                                    // is more important to continue considering it to be
17065                                    // in the background state.
17066                                    mayBeTop = true;
17067                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17068                                } else {
17069                                    // Special handling for above-top states (persistent
17070                                    // processes).  These should not bring the current process
17071                                    // into the top state, since they are not on top.  Instead
17072                                    // give them the best state after that.
17073                                    clientProcState =
17074                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17075                                }
17076                            }
17077                        } else {
17078                            if (clientProcState <
17079                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17080                                clientProcState =
17081                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17082                            }
17083                        }
17084                        if (procState > clientProcState) {
17085                            procState = clientProcState;
17086                        }
17087                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17088                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17089                            app.pendingUiClean = true;
17090                        }
17091                        if (adjType != null) {
17092                            app.adjType = adjType;
17093                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17094                                    .REASON_SERVICE_IN_USE;
17095                            app.adjSource = cr.binding.client;
17096                            app.adjSourceProcState = clientProcState;
17097                            app.adjTarget = s.name;
17098                        }
17099                    }
17100                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17101                        app.treatLikeActivity = true;
17102                    }
17103                    final ActivityRecord a = cr.activity;
17104                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17105                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17106                                (a.visible || a.state == ActivityState.RESUMED
17107                                 || a.state == ActivityState.PAUSING)) {
17108                            adj = ProcessList.FOREGROUND_APP_ADJ;
17109                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17110                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17111                            }
17112                            app.cached = false;
17113                            app.adjType = "service";
17114                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17115                                    .REASON_SERVICE_IN_USE;
17116                            app.adjSource = a;
17117                            app.adjSourceProcState = procState;
17118                            app.adjTarget = s.name;
17119                        }
17120                    }
17121                }
17122            }
17123        }
17124
17125        for (int provi = app.pubProviders.size()-1;
17126                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17127                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17128                        || procState > ActivityManager.PROCESS_STATE_TOP);
17129                provi--) {
17130            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17131            for (int i = cpr.connections.size()-1;
17132                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17133                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17134                            || procState > ActivityManager.PROCESS_STATE_TOP);
17135                    i--) {
17136                ContentProviderConnection conn = cpr.connections.get(i);
17137                ProcessRecord client = conn.client;
17138                if (client == app) {
17139                    // Being our own client is not interesting.
17140                    continue;
17141                }
17142                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17143                int clientProcState = client.curProcState;
17144                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17145                    // If the other app is cached for any reason, for purposes here
17146                    // we are going to consider it empty.
17147                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17148                }
17149                if (adj > clientAdj) {
17150                    if (app.hasShownUi && app != mHomeProcess
17151                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17152                        app.adjType = "cch-ui-provider";
17153                    } else {
17154                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17155                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17156                        app.adjType = "provider";
17157                    }
17158                    app.cached &= client.cached;
17159                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17160                            .REASON_PROVIDER_IN_USE;
17161                    app.adjSource = client;
17162                    app.adjSourceProcState = clientProcState;
17163                    app.adjTarget = cpr.name;
17164                }
17165                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17166                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17167                        // Special handling of clients who are in the top state.
17168                        // We *may* want to consider this process to be in the
17169                        // top state as well, but only if there is not another
17170                        // reason for it to be running.  Being on the top is a
17171                        // special state, meaning you are specifically running
17172                        // for the current top app.  If the process is already
17173                        // running in the background for some other reason, it
17174                        // is more important to continue considering it to be
17175                        // in the background state.
17176                        mayBeTop = true;
17177                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17178                    } else {
17179                        // Special handling for above-top states (persistent
17180                        // processes).  These should not bring the current process
17181                        // into the top state, since they are not on top.  Instead
17182                        // give them the best state after that.
17183                        clientProcState =
17184                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17185                    }
17186                }
17187                if (procState > clientProcState) {
17188                    procState = clientProcState;
17189                }
17190                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17191                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17192                }
17193            }
17194            // If the provider has external (non-framework) process
17195            // dependencies, ensure that its adjustment is at least
17196            // FOREGROUND_APP_ADJ.
17197            if (cpr.hasExternalProcessHandles()) {
17198                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17199                    adj = ProcessList.FOREGROUND_APP_ADJ;
17200                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17201                    app.cached = false;
17202                    app.adjType = "provider";
17203                    app.adjTarget = cpr.name;
17204                }
17205                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17206                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17207                }
17208            }
17209        }
17210
17211        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17212            // A client of one of our services or providers is in the top state.  We
17213            // *may* want to be in the top state, but not if we are already running in
17214            // the background for some other reason.  For the decision here, we are going
17215            // to pick out a few specific states that we want to remain in when a client
17216            // is top (states that tend to be longer-term) and otherwise allow it to go
17217            // to the top state.
17218            switch (procState) {
17219                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17220                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17221                case ActivityManager.PROCESS_STATE_SERVICE:
17222                    // These all are longer-term states, so pull them up to the top
17223                    // of the background states, but not all the way to the top state.
17224                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17225                    break;
17226                default:
17227                    // Otherwise, top is a better choice, so take it.
17228                    procState = ActivityManager.PROCESS_STATE_TOP;
17229                    break;
17230            }
17231        }
17232
17233        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17234            if (app.hasClientActivities) {
17235                // This is a cached process, but with client activities.  Mark it so.
17236                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17237                app.adjType = "cch-client-act";
17238            } else if (app.treatLikeActivity) {
17239                // This is a cached process, but somebody wants us to treat it like it has
17240                // an activity, okay!
17241                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17242                app.adjType = "cch-as-act";
17243            }
17244        }
17245
17246        if (adj == ProcessList.SERVICE_ADJ) {
17247            if (doingAll) {
17248                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17249                mNewNumServiceProcs++;
17250                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17251                if (!app.serviceb) {
17252                    // This service isn't far enough down on the LRU list to
17253                    // normally be a B service, but if we are low on RAM and it
17254                    // is large we want to force it down since we would prefer to
17255                    // keep launcher over it.
17256                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17257                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17258                        app.serviceHighRam = true;
17259                        app.serviceb = true;
17260                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17261                    } else {
17262                        mNewNumAServiceProcs++;
17263                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17264                    }
17265                } else {
17266                    app.serviceHighRam = false;
17267                }
17268            }
17269            if (app.serviceb) {
17270                adj = ProcessList.SERVICE_B_ADJ;
17271            }
17272        }
17273
17274        app.curRawAdj = adj;
17275
17276        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17277        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17278        if (adj > app.maxAdj) {
17279            adj = app.maxAdj;
17280            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17281                schedGroup = Process.THREAD_GROUP_DEFAULT;
17282            }
17283        }
17284
17285        // Do final modification to adj.  Everything we do between here and applying
17286        // the final setAdj must be done in this function, because we will also use
17287        // it when computing the final cached adj later.  Note that we don't need to
17288        // worry about this for max adj above, since max adj will always be used to
17289        // keep it out of the cached vaues.
17290        app.curAdj = app.modifyRawOomAdj(adj);
17291        app.curSchedGroup = schedGroup;
17292        app.curProcState = procState;
17293        app.foregroundActivities = foregroundActivities;
17294
17295        return app.curRawAdj;
17296    }
17297
17298    /**
17299     * Schedule PSS collection of a process.
17300     */
17301    void requestPssLocked(ProcessRecord proc, int procState) {
17302        if (mPendingPssProcesses.contains(proc)) {
17303            return;
17304        }
17305        if (mPendingPssProcesses.size() == 0) {
17306            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17307        }
17308        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17309        proc.pssProcState = procState;
17310        mPendingPssProcesses.add(proc);
17311    }
17312
17313    /**
17314     * Schedule PSS collection of all processes.
17315     */
17316    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17317        if (!always) {
17318            if (now < (mLastFullPssTime +
17319                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17320                return;
17321            }
17322        }
17323        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17324        mLastFullPssTime = now;
17325        mFullPssPending = true;
17326        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17327        mPendingPssProcesses.clear();
17328        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17329            ProcessRecord app = mLruProcesses.get(i);
17330            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17331                app.pssProcState = app.setProcState;
17332                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17333                        isSleeping(), now);
17334                mPendingPssProcesses.add(app);
17335            }
17336        }
17337        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17338    }
17339
17340    /**
17341     * Ask a given process to GC right now.
17342     */
17343    final void performAppGcLocked(ProcessRecord app) {
17344        try {
17345            app.lastRequestedGc = SystemClock.uptimeMillis();
17346            if (app.thread != null) {
17347                if (app.reportLowMemory) {
17348                    app.reportLowMemory = false;
17349                    app.thread.scheduleLowMemory();
17350                } else {
17351                    app.thread.processInBackground();
17352                }
17353            }
17354        } catch (Exception e) {
17355            // whatever.
17356        }
17357    }
17358
17359    /**
17360     * Returns true if things are idle enough to perform GCs.
17361     */
17362    private final boolean canGcNowLocked() {
17363        boolean processingBroadcasts = false;
17364        for (BroadcastQueue q : mBroadcastQueues) {
17365            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17366                processingBroadcasts = true;
17367            }
17368        }
17369        return !processingBroadcasts
17370                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17371    }
17372
17373    /**
17374     * Perform GCs on all processes that are waiting for it, but only
17375     * if things are idle.
17376     */
17377    final void performAppGcsLocked() {
17378        final int N = mProcessesToGc.size();
17379        if (N <= 0) {
17380            return;
17381        }
17382        if (canGcNowLocked()) {
17383            while (mProcessesToGc.size() > 0) {
17384                ProcessRecord proc = mProcessesToGc.remove(0);
17385                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17386                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17387                            <= SystemClock.uptimeMillis()) {
17388                        // To avoid spamming the system, we will GC processes one
17389                        // at a time, waiting a few seconds between each.
17390                        performAppGcLocked(proc);
17391                        scheduleAppGcsLocked();
17392                        return;
17393                    } else {
17394                        // It hasn't been long enough since we last GCed this
17395                        // process...  put it in the list to wait for its time.
17396                        addProcessToGcListLocked(proc);
17397                        break;
17398                    }
17399                }
17400            }
17401
17402            scheduleAppGcsLocked();
17403        }
17404    }
17405
17406    /**
17407     * If all looks good, perform GCs on all processes waiting for them.
17408     */
17409    final void performAppGcsIfAppropriateLocked() {
17410        if (canGcNowLocked()) {
17411            performAppGcsLocked();
17412            return;
17413        }
17414        // Still not idle, wait some more.
17415        scheduleAppGcsLocked();
17416    }
17417
17418    /**
17419     * Schedule the execution of all pending app GCs.
17420     */
17421    final void scheduleAppGcsLocked() {
17422        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17423
17424        if (mProcessesToGc.size() > 0) {
17425            // Schedule a GC for the time to the next process.
17426            ProcessRecord proc = mProcessesToGc.get(0);
17427            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17428
17429            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17430            long now = SystemClock.uptimeMillis();
17431            if (when < (now+GC_TIMEOUT)) {
17432                when = now + GC_TIMEOUT;
17433            }
17434            mHandler.sendMessageAtTime(msg, when);
17435        }
17436    }
17437
17438    /**
17439     * Add a process to the array of processes waiting to be GCed.  Keeps the
17440     * list in sorted order by the last GC time.  The process can't already be
17441     * on the list.
17442     */
17443    final void addProcessToGcListLocked(ProcessRecord proc) {
17444        boolean added = false;
17445        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17446            if (mProcessesToGc.get(i).lastRequestedGc <
17447                    proc.lastRequestedGc) {
17448                added = true;
17449                mProcessesToGc.add(i+1, proc);
17450                break;
17451            }
17452        }
17453        if (!added) {
17454            mProcessesToGc.add(0, proc);
17455        }
17456    }
17457
17458    /**
17459     * Set up to ask a process to GC itself.  This will either do it
17460     * immediately, or put it on the list of processes to gc the next
17461     * time things are idle.
17462     */
17463    final void scheduleAppGcLocked(ProcessRecord app) {
17464        long now = SystemClock.uptimeMillis();
17465        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17466            return;
17467        }
17468        if (!mProcessesToGc.contains(app)) {
17469            addProcessToGcListLocked(app);
17470            scheduleAppGcsLocked();
17471        }
17472    }
17473
17474    final void checkExcessivePowerUsageLocked(boolean doKills) {
17475        updateCpuStatsNow();
17476
17477        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17478        boolean doWakeKills = doKills;
17479        boolean doCpuKills = doKills;
17480        if (mLastPowerCheckRealtime == 0) {
17481            doWakeKills = false;
17482        }
17483        if (mLastPowerCheckUptime == 0) {
17484            doCpuKills = false;
17485        }
17486        if (stats.isScreenOn()) {
17487            doWakeKills = false;
17488        }
17489        final long curRealtime = SystemClock.elapsedRealtime();
17490        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17491        final long curUptime = SystemClock.uptimeMillis();
17492        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17493        mLastPowerCheckRealtime = curRealtime;
17494        mLastPowerCheckUptime = curUptime;
17495        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17496            doWakeKills = false;
17497        }
17498        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17499            doCpuKills = false;
17500        }
17501        int i = mLruProcesses.size();
17502        while (i > 0) {
17503            i--;
17504            ProcessRecord app = mLruProcesses.get(i);
17505            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17506                long wtime;
17507                synchronized (stats) {
17508                    wtime = stats.getProcessWakeTime(app.info.uid,
17509                            app.pid, curRealtime);
17510                }
17511                long wtimeUsed = wtime - app.lastWakeTime;
17512                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17513                if (DEBUG_POWER) {
17514                    StringBuilder sb = new StringBuilder(128);
17515                    sb.append("Wake for ");
17516                    app.toShortString(sb);
17517                    sb.append(": over ");
17518                    TimeUtils.formatDuration(realtimeSince, sb);
17519                    sb.append(" used ");
17520                    TimeUtils.formatDuration(wtimeUsed, sb);
17521                    sb.append(" (");
17522                    sb.append((wtimeUsed*100)/realtimeSince);
17523                    sb.append("%)");
17524                    Slog.i(TAG, sb.toString());
17525                    sb.setLength(0);
17526                    sb.append("CPU for ");
17527                    app.toShortString(sb);
17528                    sb.append(": over ");
17529                    TimeUtils.formatDuration(uptimeSince, sb);
17530                    sb.append(" used ");
17531                    TimeUtils.formatDuration(cputimeUsed, sb);
17532                    sb.append(" (");
17533                    sb.append((cputimeUsed*100)/uptimeSince);
17534                    sb.append("%)");
17535                    Slog.i(TAG, sb.toString());
17536                }
17537                // If a process has held a wake lock for more
17538                // than 50% of the time during this period,
17539                // that sounds bad.  Kill!
17540                if (doWakeKills && realtimeSince > 0
17541                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17542                    synchronized (stats) {
17543                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17544                                realtimeSince, wtimeUsed);
17545                    }
17546                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17547                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17548                } else if (doCpuKills && uptimeSince > 0
17549                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17550                    synchronized (stats) {
17551                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17552                                uptimeSince, cputimeUsed);
17553                    }
17554                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17555                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17556                } else {
17557                    app.lastWakeTime = wtime;
17558                    app.lastCpuTime = app.curCpuTime;
17559                }
17560            }
17561        }
17562    }
17563
17564    private final boolean applyOomAdjLocked(ProcessRecord app,
17565            ProcessRecord TOP_APP, boolean doingAll, long now) {
17566        boolean success = true;
17567
17568        if (app.curRawAdj != app.setRawAdj) {
17569            app.setRawAdj = app.curRawAdj;
17570        }
17571
17572        int changes = 0;
17573
17574        if (app.curAdj != app.setAdj) {
17575            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17576            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17577                TAG, "Set " + app.pid + " " + app.processName +
17578                " adj " + app.curAdj + ": " + app.adjType);
17579            app.setAdj = app.curAdj;
17580        }
17581
17582        if (app.setSchedGroup != app.curSchedGroup) {
17583            app.setSchedGroup = app.curSchedGroup;
17584            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17585                    "Setting process group of " + app.processName
17586                    + " to " + app.curSchedGroup);
17587            if (app.waitingToKill != null &&
17588                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17589                app.kill(app.waitingToKill, true);
17590                success = false;
17591            } else {
17592                if (true) {
17593                    long oldId = Binder.clearCallingIdentity();
17594                    try {
17595                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17596                    } catch (Exception e) {
17597                        Slog.w(TAG, "Failed setting process group of " + app.pid
17598                                + " to " + app.curSchedGroup);
17599                        e.printStackTrace();
17600                    } finally {
17601                        Binder.restoreCallingIdentity(oldId);
17602                    }
17603                } else {
17604                    if (app.thread != null) {
17605                        try {
17606                            app.thread.setSchedulingGroup(app.curSchedGroup);
17607                        } catch (RemoteException e) {
17608                        }
17609                    }
17610                }
17611                Process.setSwappiness(app.pid,
17612                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17613            }
17614        }
17615        if (app.repForegroundActivities != app.foregroundActivities) {
17616            app.repForegroundActivities = app.foregroundActivities;
17617            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17618        }
17619        if (app.repProcState != app.curProcState) {
17620            app.repProcState = app.curProcState;
17621            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17622            if (app.thread != null) {
17623                try {
17624                    if (false) {
17625                        //RuntimeException h = new RuntimeException("here");
17626                        Slog.i(TAG, "Sending new process state " + app.repProcState
17627                                + " to " + app /*, h*/);
17628                    }
17629                    app.thread.setProcessState(app.repProcState);
17630                } catch (RemoteException e) {
17631                }
17632            }
17633        }
17634        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17635                app.setProcState)) {
17636            app.lastStateTime = now;
17637            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17638                    isSleeping(), now);
17639            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17640                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17641                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17642                    + (app.nextPssTime-now) + ": " + app);
17643        } else {
17644            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17645                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17646                requestPssLocked(app, app.setProcState);
17647                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17648                        isSleeping(), now);
17649            } else if (false && DEBUG_PSS) {
17650                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17651            }
17652        }
17653        if (app.setProcState != app.curProcState) {
17654            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17655                    "Proc state change of " + app.processName
17656                    + " to " + app.curProcState);
17657            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17658            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17659            if (setImportant && !curImportant) {
17660                // This app is no longer something we consider important enough to allow to
17661                // use arbitrary amounts of battery power.  Note
17662                // its current wake lock time to later know to kill it if
17663                // it is not behaving well.
17664                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17665                synchronized (stats) {
17666                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17667                            app.pid, SystemClock.elapsedRealtime());
17668                }
17669                app.lastCpuTime = app.curCpuTime;
17670
17671            }
17672            app.setProcState = app.curProcState;
17673            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17674                app.notCachedSinceIdle = false;
17675            }
17676            if (!doingAll) {
17677                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17678            } else {
17679                app.procStateChanged = true;
17680            }
17681        }
17682
17683        if (changes != 0) {
17684            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17685            int i = mPendingProcessChanges.size()-1;
17686            ProcessChangeItem item = null;
17687            while (i >= 0) {
17688                item = mPendingProcessChanges.get(i);
17689                if (item.pid == app.pid) {
17690                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17691                    break;
17692                }
17693                i--;
17694            }
17695            if (i < 0) {
17696                // No existing item in pending changes; need a new one.
17697                final int NA = mAvailProcessChanges.size();
17698                if (NA > 0) {
17699                    item = mAvailProcessChanges.remove(NA-1);
17700                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17701                } else {
17702                    item = new ProcessChangeItem();
17703                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17704                }
17705                item.changes = 0;
17706                item.pid = app.pid;
17707                item.uid = app.info.uid;
17708                if (mPendingProcessChanges.size() == 0) {
17709                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17710                            "*** Enqueueing dispatch processes changed!");
17711                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17712                }
17713                mPendingProcessChanges.add(item);
17714            }
17715            item.changes |= changes;
17716            item.processState = app.repProcState;
17717            item.foregroundActivities = app.repForegroundActivities;
17718            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17719                    + Integer.toHexString(System.identityHashCode(item))
17720                    + " " + app.toShortString() + ": changes=" + item.changes
17721                    + " procState=" + item.processState
17722                    + " foreground=" + item.foregroundActivities
17723                    + " type=" + app.adjType + " source=" + app.adjSource
17724                    + " target=" + app.adjTarget);
17725        }
17726
17727        return success;
17728    }
17729
17730    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17731        if (proc.thread != null) {
17732            if (proc.baseProcessTracker != null) {
17733                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17734            }
17735            if (proc.repProcState >= 0) {
17736                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17737                        proc.repProcState);
17738            }
17739        }
17740    }
17741
17742    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17743            ProcessRecord TOP_APP, boolean doingAll, long now) {
17744        if (app.thread == null) {
17745            return false;
17746        }
17747
17748        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17749
17750        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17751    }
17752
17753    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17754            boolean oomAdj) {
17755        if (isForeground != proc.foregroundServices) {
17756            proc.foregroundServices = isForeground;
17757            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17758                    proc.info.uid);
17759            if (isForeground) {
17760                if (curProcs == null) {
17761                    curProcs = new ArrayList<ProcessRecord>();
17762                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17763                }
17764                if (!curProcs.contains(proc)) {
17765                    curProcs.add(proc);
17766                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17767                            proc.info.packageName, proc.info.uid);
17768                }
17769            } else {
17770                if (curProcs != null) {
17771                    if (curProcs.remove(proc)) {
17772                        mBatteryStatsService.noteEvent(
17773                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17774                                proc.info.packageName, proc.info.uid);
17775                        if (curProcs.size() <= 0) {
17776                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17777                        }
17778                    }
17779                }
17780            }
17781            if (oomAdj) {
17782                updateOomAdjLocked();
17783            }
17784        }
17785    }
17786
17787    private final ActivityRecord resumedAppLocked() {
17788        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17789        String pkg;
17790        int uid;
17791        if (act != null) {
17792            pkg = act.packageName;
17793            uid = act.info.applicationInfo.uid;
17794        } else {
17795            pkg = null;
17796            uid = -1;
17797        }
17798        // Has the UID or resumed package name changed?
17799        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17800                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17801            if (mCurResumedPackage != null) {
17802                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17803                        mCurResumedPackage, mCurResumedUid);
17804            }
17805            mCurResumedPackage = pkg;
17806            mCurResumedUid = uid;
17807            if (mCurResumedPackage != null) {
17808                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17809                        mCurResumedPackage, mCurResumedUid);
17810            }
17811        }
17812        return act;
17813    }
17814
17815    final boolean updateOomAdjLocked(ProcessRecord app) {
17816        final ActivityRecord TOP_ACT = resumedAppLocked();
17817        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17818        final boolean wasCached = app.cached;
17819
17820        mAdjSeq++;
17821
17822        // This is the desired cached adjusment we want to tell it to use.
17823        // If our app is currently cached, we know it, and that is it.  Otherwise,
17824        // we don't know it yet, and it needs to now be cached we will then
17825        // need to do a complete oom adj.
17826        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17827                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17828        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17829                SystemClock.uptimeMillis());
17830        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17831            // Changed to/from cached state, so apps after it in the LRU
17832            // list may also be changed.
17833            updateOomAdjLocked();
17834        }
17835        return success;
17836    }
17837
17838    final void updateOomAdjLocked() {
17839        final ActivityRecord TOP_ACT = resumedAppLocked();
17840        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17841        final long now = SystemClock.uptimeMillis();
17842        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17843        final int N = mLruProcesses.size();
17844
17845        if (false) {
17846            RuntimeException e = new RuntimeException();
17847            e.fillInStackTrace();
17848            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17849        }
17850
17851        mAdjSeq++;
17852        mNewNumServiceProcs = 0;
17853        mNewNumAServiceProcs = 0;
17854
17855        final int emptyProcessLimit;
17856        final int cachedProcessLimit;
17857        if (mProcessLimit <= 0) {
17858            emptyProcessLimit = cachedProcessLimit = 0;
17859        } else if (mProcessLimit == 1) {
17860            emptyProcessLimit = 1;
17861            cachedProcessLimit = 0;
17862        } else {
17863            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17864            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17865        }
17866
17867        // Let's determine how many processes we have running vs.
17868        // how many slots we have for background processes; we may want
17869        // to put multiple processes in a slot of there are enough of
17870        // them.
17871        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17872                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17873        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17874        if (numEmptyProcs > cachedProcessLimit) {
17875            // If there are more empty processes than our limit on cached
17876            // processes, then use the cached process limit for the factor.
17877            // This ensures that the really old empty processes get pushed
17878            // down to the bottom, so if we are running low on memory we will
17879            // have a better chance at keeping around more cached processes
17880            // instead of a gazillion empty processes.
17881            numEmptyProcs = cachedProcessLimit;
17882        }
17883        int emptyFactor = numEmptyProcs/numSlots;
17884        if (emptyFactor < 1) emptyFactor = 1;
17885        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17886        if (cachedFactor < 1) cachedFactor = 1;
17887        int stepCached = 0;
17888        int stepEmpty = 0;
17889        int numCached = 0;
17890        int numEmpty = 0;
17891        int numTrimming = 0;
17892
17893        mNumNonCachedProcs = 0;
17894        mNumCachedHiddenProcs = 0;
17895
17896        // First update the OOM adjustment for each of the
17897        // application processes based on their current state.
17898        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17899        int nextCachedAdj = curCachedAdj+1;
17900        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17901        int nextEmptyAdj = curEmptyAdj+2;
17902        for (int i=N-1; i>=0; i--) {
17903            ProcessRecord app = mLruProcesses.get(i);
17904            if (!app.killedByAm && app.thread != null) {
17905                app.procStateChanged = false;
17906                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17907
17908                // If we haven't yet assigned the final cached adj
17909                // to the process, do that now.
17910                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17911                    switch (app.curProcState) {
17912                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17913                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17914                            // This process is a cached process holding activities...
17915                            // assign it the next cached value for that type, and then
17916                            // step that cached level.
17917                            app.curRawAdj = curCachedAdj;
17918                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17919                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17920                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17921                                    + ")");
17922                            if (curCachedAdj != nextCachedAdj) {
17923                                stepCached++;
17924                                if (stepCached >= cachedFactor) {
17925                                    stepCached = 0;
17926                                    curCachedAdj = nextCachedAdj;
17927                                    nextCachedAdj += 2;
17928                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17929                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17930                                    }
17931                                }
17932                            }
17933                            break;
17934                        default:
17935                            // For everything else, assign next empty cached process
17936                            // level and bump that up.  Note that this means that
17937                            // long-running services that have dropped down to the
17938                            // cached level will be treated as empty (since their process
17939                            // state is still as a service), which is what we want.
17940                            app.curRawAdj = curEmptyAdj;
17941                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17942                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17943                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17944                                    + ")");
17945                            if (curEmptyAdj != nextEmptyAdj) {
17946                                stepEmpty++;
17947                                if (stepEmpty >= emptyFactor) {
17948                                    stepEmpty = 0;
17949                                    curEmptyAdj = nextEmptyAdj;
17950                                    nextEmptyAdj += 2;
17951                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17952                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17953                                    }
17954                                }
17955                            }
17956                            break;
17957                    }
17958                }
17959
17960                applyOomAdjLocked(app, TOP_APP, true, now);
17961
17962                // Count the number of process types.
17963                switch (app.curProcState) {
17964                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17965                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17966                        mNumCachedHiddenProcs++;
17967                        numCached++;
17968                        if (numCached > cachedProcessLimit) {
17969                            app.kill("cached #" + numCached, true);
17970                        }
17971                        break;
17972                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17973                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17974                                && app.lastActivityTime < oldTime) {
17975                            app.kill("empty for "
17976                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17977                                    / 1000) + "s", true);
17978                        } else {
17979                            numEmpty++;
17980                            if (numEmpty > emptyProcessLimit) {
17981                                app.kill("empty #" + numEmpty, true);
17982                            }
17983                        }
17984                        break;
17985                    default:
17986                        mNumNonCachedProcs++;
17987                        break;
17988                }
17989
17990                if (app.isolated && app.services.size() <= 0) {
17991                    // If this is an isolated process, and there are no
17992                    // services running in it, then the process is no longer
17993                    // needed.  We agressively kill these because we can by
17994                    // definition not re-use the same process again, and it is
17995                    // good to avoid having whatever code was running in them
17996                    // left sitting around after no longer needed.
17997                    app.kill("isolated not needed", true);
17998                }
17999
18000                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18001                        && !app.killedByAm) {
18002                    numTrimming++;
18003                }
18004            }
18005        }
18006
18007        mNumServiceProcs = mNewNumServiceProcs;
18008
18009        // Now determine the memory trimming level of background processes.
18010        // Unfortunately we need to start at the back of the list to do this
18011        // properly.  We only do this if the number of background apps we
18012        // are managing to keep around is less than half the maximum we desire;
18013        // if we are keeping a good number around, we'll let them use whatever
18014        // memory they want.
18015        final int numCachedAndEmpty = numCached + numEmpty;
18016        int memFactor;
18017        if (numCached <= ProcessList.TRIM_CACHED_APPS
18018                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18019            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18020                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18021            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18022                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18023            } else {
18024                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18025            }
18026        } else {
18027            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18028        }
18029        // We always allow the memory level to go up (better).  We only allow it to go
18030        // down if we are in a state where that is allowed, *and* the total number of processes
18031        // has gone down since last time.
18032        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18033                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18034                + " last=" + mLastNumProcesses);
18035        if (memFactor > mLastMemoryLevel) {
18036            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18037                memFactor = mLastMemoryLevel;
18038                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18039            }
18040        }
18041        mLastMemoryLevel = memFactor;
18042        mLastNumProcesses = mLruProcesses.size();
18043        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18044        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18045        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18046            if (mLowRamStartTime == 0) {
18047                mLowRamStartTime = now;
18048            }
18049            int step = 0;
18050            int fgTrimLevel;
18051            switch (memFactor) {
18052                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18053                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18054                    break;
18055                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18056                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18057                    break;
18058                default:
18059                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18060                    break;
18061            }
18062            int factor = numTrimming/3;
18063            int minFactor = 2;
18064            if (mHomeProcess != null) minFactor++;
18065            if (mPreviousProcess != null) minFactor++;
18066            if (factor < minFactor) factor = minFactor;
18067            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18068            for (int i=N-1; i>=0; i--) {
18069                ProcessRecord app = mLruProcesses.get(i);
18070                if (allChanged || app.procStateChanged) {
18071                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18072                    app.procStateChanged = false;
18073                }
18074                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18075                        && !app.killedByAm) {
18076                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18077                        try {
18078                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18079                                    "Trimming memory of " + app.processName
18080                                    + " to " + curLevel);
18081                            app.thread.scheduleTrimMemory(curLevel);
18082                        } catch (RemoteException e) {
18083                        }
18084                        if (false) {
18085                            // For now we won't do this; our memory trimming seems
18086                            // to be good enough at this point that destroying
18087                            // activities causes more harm than good.
18088                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18089                                    && app != mHomeProcess && app != mPreviousProcess) {
18090                                // Need to do this on its own message because the stack may not
18091                                // be in a consistent state at this point.
18092                                // For these apps we will also finish their activities
18093                                // to help them free memory.
18094                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18095                            }
18096                        }
18097                    }
18098                    app.trimMemoryLevel = curLevel;
18099                    step++;
18100                    if (step >= factor) {
18101                        step = 0;
18102                        switch (curLevel) {
18103                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18104                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18105                                break;
18106                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18107                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18108                                break;
18109                        }
18110                    }
18111                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18112                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18113                            && app.thread != null) {
18114                        try {
18115                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18116                                    "Trimming memory of heavy-weight " + app.processName
18117                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18118                            app.thread.scheduleTrimMemory(
18119                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18120                        } catch (RemoteException e) {
18121                        }
18122                    }
18123                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18124                } else {
18125                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18126                            || app.systemNoUi) && app.pendingUiClean) {
18127                        // If this application is now in the background and it
18128                        // had done UI, then give it the special trim level to
18129                        // have it free UI resources.
18130                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18131                        if (app.trimMemoryLevel < level && app.thread != null) {
18132                            try {
18133                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18134                                        "Trimming memory of bg-ui " + app.processName
18135                                        + " to " + level);
18136                                app.thread.scheduleTrimMemory(level);
18137                            } catch (RemoteException e) {
18138                            }
18139                        }
18140                        app.pendingUiClean = false;
18141                    }
18142                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18143                        try {
18144                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18145                                    "Trimming memory of fg " + app.processName
18146                                    + " to " + fgTrimLevel);
18147                            app.thread.scheduleTrimMemory(fgTrimLevel);
18148                        } catch (RemoteException e) {
18149                        }
18150                    }
18151                    app.trimMemoryLevel = fgTrimLevel;
18152                }
18153            }
18154        } else {
18155            if (mLowRamStartTime != 0) {
18156                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18157                mLowRamStartTime = 0;
18158            }
18159            for (int i=N-1; i>=0; i--) {
18160                ProcessRecord app = mLruProcesses.get(i);
18161                if (allChanged || app.procStateChanged) {
18162                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18163                    app.procStateChanged = false;
18164                }
18165                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18166                        || app.systemNoUi) && app.pendingUiClean) {
18167                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18168                            && app.thread != null) {
18169                        try {
18170                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18171                                    "Trimming memory of ui hidden " + app.processName
18172                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18173                            app.thread.scheduleTrimMemory(
18174                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18175                        } catch (RemoteException e) {
18176                        }
18177                    }
18178                    app.pendingUiClean = false;
18179                }
18180                app.trimMemoryLevel = 0;
18181            }
18182        }
18183
18184        if (mAlwaysFinishActivities) {
18185            // Need to do this on its own message because the stack may not
18186            // be in a consistent state at this point.
18187            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18188        }
18189
18190        if (allChanged) {
18191            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18192        }
18193
18194        if (mProcessStats.shouldWriteNowLocked(now)) {
18195            mHandler.post(new Runnable() {
18196                @Override public void run() {
18197                    synchronized (ActivityManagerService.this) {
18198                        mProcessStats.writeStateAsyncLocked();
18199                    }
18200                }
18201            });
18202        }
18203
18204        if (DEBUG_OOM_ADJ) {
18205            if (false) {
18206                RuntimeException here = new RuntimeException("here");
18207                here.fillInStackTrace();
18208                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18209            } else {
18210                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18211            }
18212        }
18213    }
18214
18215    final void trimApplications() {
18216        synchronized (this) {
18217            int i;
18218
18219            // First remove any unused application processes whose package
18220            // has been removed.
18221            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18222                final ProcessRecord app = mRemovedProcesses.get(i);
18223                if (app.activities.size() == 0
18224                        && app.curReceiver == null && app.services.size() == 0) {
18225                    Slog.i(
18226                        TAG, "Exiting empty application process "
18227                        + app.processName + " ("
18228                        + (app.thread != null ? app.thread.asBinder() : null)
18229                        + ")\n");
18230                    if (app.pid > 0 && app.pid != MY_PID) {
18231                        app.kill("empty", false);
18232                    } else {
18233                        try {
18234                            app.thread.scheduleExit();
18235                        } catch (Exception e) {
18236                            // Ignore exceptions.
18237                        }
18238                    }
18239                    cleanUpApplicationRecordLocked(app, false, true, -1);
18240                    mRemovedProcesses.remove(i);
18241
18242                    if (app.persistent) {
18243                        addAppLocked(app.info, false, null /* ABI override */);
18244                    }
18245                }
18246            }
18247
18248            // Now update the oom adj for all processes.
18249            updateOomAdjLocked();
18250        }
18251    }
18252
18253    /** This method sends the specified signal to each of the persistent apps */
18254    public void signalPersistentProcesses(int sig) throws RemoteException {
18255        if (sig != Process.SIGNAL_USR1) {
18256            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18257        }
18258
18259        synchronized (this) {
18260            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18261                    != PackageManager.PERMISSION_GRANTED) {
18262                throw new SecurityException("Requires permission "
18263                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18264            }
18265
18266            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18267                ProcessRecord r = mLruProcesses.get(i);
18268                if (r.thread != null && r.persistent) {
18269                    Process.sendSignal(r.pid, sig);
18270                }
18271            }
18272        }
18273    }
18274
18275    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18276        if (proc == null || proc == mProfileProc) {
18277            proc = mProfileProc;
18278            profileType = mProfileType;
18279            clearProfilerLocked();
18280        }
18281        if (proc == null) {
18282            return;
18283        }
18284        try {
18285            proc.thread.profilerControl(false, null, profileType);
18286        } catch (RemoteException e) {
18287            throw new IllegalStateException("Process disappeared");
18288        }
18289    }
18290
18291    private void clearProfilerLocked() {
18292        if (mProfileFd != null) {
18293            try {
18294                mProfileFd.close();
18295            } catch (IOException e) {
18296            }
18297        }
18298        mProfileApp = null;
18299        mProfileProc = null;
18300        mProfileFile = null;
18301        mProfileType = 0;
18302        mAutoStopProfiler = false;
18303        mSamplingInterval = 0;
18304    }
18305
18306    public boolean profileControl(String process, int userId, boolean start,
18307            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18308
18309        try {
18310            synchronized (this) {
18311                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18312                // its own permission.
18313                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18314                        != PackageManager.PERMISSION_GRANTED) {
18315                    throw new SecurityException("Requires permission "
18316                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18317                }
18318
18319                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18320                    throw new IllegalArgumentException("null profile info or fd");
18321                }
18322
18323                ProcessRecord proc = null;
18324                if (process != null) {
18325                    proc = findProcessLocked(process, userId, "profileControl");
18326                }
18327
18328                if (start && (proc == null || proc.thread == null)) {
18329                    throw new IllegalArgumentException("Unknown process: " + process);
18330                }
18331
18332                if (start) {
18333                    stopProfilerLocked(null, 0);
18334                    setProfileApp(proc.info, proc.processName, profilerInfo);
18335                    mProfileProc = proc;
18336                    mProfileType = profileType;
18337                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18338                    try {
18339                        fd = fd.dup();
18340                    } catch (IOException e) {
18341                        fd = null;
18342                    }
18343                    profilerInfo.profileFd = fd;
18344                    proc.thread.profilerControl(start, profilerInfo, profileType);
18345                    fd = null;
18346                    mProfileFd = null;
18347                } else {
18348                    stopProfilerLocked(proc, profileType);
18349                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18350                        try {
18351                            profilerInfo.profileFd.close();
18352                        } catch (IOException e) {
18353                        }
18354                    }
18355                }
18356
18357                return true;
18358            }
18359        } catch (RemoteException e) {
18360            throw new IllegalStateException("Process disappeared");
18361        } finally {
18362            if (profilerInfo != null && profilerInfo.profileFd != null) {
18363                try {
18364                    profilerInfo.profileFd.close();
18365                } catch (IOException e) {
18366                }
18367            }
18368        }
18369    }
18370
18371    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18372        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18373                userId, true, ALLOW_FULL_ONLY, callName, null);
18374        ProcessRecord proc = null;
18375        try {
18376            int pid = Integer.parseInt(process);
18377            synchronized (mPidsSelfLocked) {
18378                proc = mPidsSelfLocked.get(pid);
18379            }
18380        } catch (NumberFormatException e) {
18381        }
18382
18383        if (proc == null) {
18384            ArrayMap<String, SparseArray<ProcessRecord>> all
18385                    = mProcessNames.getMap();
18386            SparseArray<ProcessRecord> procs = all.get(process);
18387            if (procs != null && procs.size() > 0) {
18388                proc = procs.valueAt(0);
18389                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18390                    for (int i=1; i<procs.size(); i++) {
18391                        ProcessRecord thisProc = procs.valueAt(i);
18392                        if (thisProc.userId == userId) {
18393                            proc = thisProc;
18394                            break;
18395                        }
18396                    }
18397                }
18398            }
18399        }
18400
18401        return proc;
18402    }
18403
18404    public boolean dumpHeap(String process, int userId, boolean managed,
18405            String path, ParcelFileDescriptor fd) throws RemoteException {
18406
18407        try {
18408            synchronized (this) {
18409                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18410                // its own permission (same as profileControl).
18411                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18412                        != PackageManager.PERMISSION_GRANTED) {
18413                    throw new SecurityException("Requires permission "
18414                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18415                }
18416
18417                if (fd == null) {
18418                    throw new IllegalArgumentException("null fd");
18419                }
18420
18421                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18422                if (proc == null || proc.thread == null) {
18423                    throw new IllegalArgumentException("Unknown process: " + process);
18424                }
18425
18426                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18427                if (!isDebuggable) {
18428                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18429                        throw new SecurityException("Process not debuggable: " + proc);
18430                    }
18431                }
18432
18433                proc.thread.dumpHeap(managed, path, fd);
18434                fd = null;
18435                return true;
18436            }
18437        } catch (RemoteException e) {
18438            throw new IllegalStateException("Process disappeared");
18439        } finally {
18440            if (fd != null) {
18441                try {
18442                    fd.close();
18443                } catch (IOException e) {
18444                }
18445            }
18446        }
18447    }
18448
18449    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18450    public void monitor() {
18451        synchronized (this) { }
18452    }
18453
18454    void onCoreSettingsChange(Bundle settings) {
18455        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18456            ProcessRecord processRecord = mLruProcesses.get(i);
18457            try {
18458                if (processRecord.thread != null) {
18459                    processRecord.thread.setCoreSettings(settings);
18460                }
18461            } catch (RemoteException re) {
18462                /* ignore */
18463            }
18464        }
18465    }
18466
18467    // Multi-user methods
18468
18469    /**
18470     * Start user, if its not already running, but don't bring it to foreground.
18471     */
18472    @Override
18473    public boolean startUserInBackground(final int userId) {
18474        return startUser(userId, /* foreground */ false);
18475    }
18476
18477    /**
18478     * Start user, if its not already running, and bring it to foreground.
18479     */
18480    boolean startUserInForeground(final int userId, Dialog dlg) {
18481        boolean result = startUser(userId, /* foreground */ true);
18482        dlg.dismiss();
18483        return result;
18484    }
18485
18486    /**
18487     * Refreshes the list of users related to the current user when either a
18488     * user switch happens or when a new related user is started in the
18489     * background.
18490     */
18491    private void updateCurrentProfileIdsLocked() {
18492        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18493                mCurrentUserId, false /* enabledOnly */);
18494        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18495        for (int i = 0; i < currentProfileIds.length; i++) {
18496            currentProfileIds[i] = profiles.get(i).id;
18497        }
18498        mCurrentProfileIds = currentProfileIds;
18499
18500        synchronized (mUserProfileGroupIdsSelfLocked) {
18501            mUserProfileGroupIdsSelfLocked.clear();
18502            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18503            for (int i = 0; i < users.size(); i++) {
18504                UserInfo user = users.get(i);
18505                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18506                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18507                }
18508            }
18509        }
18510    }
18511
18512    private Set getProfileIdsLocked(int userId) {
18513        Set userIds = new HashSet<Integer>();
18514        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18515                userId, false /* enabledOnly */);
18516        for (UserInfo user : profiles) {
18517            userIds.add(Integer.valueOf(user.id));
18518        }
18519        return userIds;
18520    }
18521
18522    @Override
18523    public boolean switchUser(final int userId) {
18524        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18525        String userName;
18526        synchronized (this) {
18527            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18528            if (userInfo == null) {
18529                Slog.w(TAG, "No user info for user #" + userId);
18530                return false;
18531            }
18532            if (userInfo.isManagedProfile()) {
18533                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18534                return false;
18535            }
18536            userName = userInfo.name;
18537            mTargetUserId = userId;
18538        }
18539        mHandler.removeMessages(START_USER_SWITCH_MSG);
18540        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18541        return true;
18542    }
18543
18544    private void showUserSwitchDialog(int userId, String userName) {
18545        // The dialog will show and then initiate the user switch by calling startUserInForeground
18546        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18547                true /* above system */);
18548        d.show();
18549    }
18550
18551    private boolean startUser(final int userId, final boolean foreground) {
18552        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18553                != PackageManager.PERMISSION_GRANTED) {
18554            String msg = "Permission Denial: switchUser() from pid="
18555                    + Binder.getCallingPid()
18556                    + ", uid=" + Binder.getCallingUid()
18557                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18558            Slog.w(TAG, msg);
18559            throw new SecurityException(msg);
18560        }
18561
18562        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18563
18564        final long ident = Binder.clearCallingIdentity();
18565        try {
18566            synchronized (this) {
18567                final int oldUserId = mCurrentUserId;
18568                if (oldUserId == userId) {
18569                    return true;
18570                }
18571
18572                mStackSupervisor.setLockTaskModeLocked(null, false);
18573
18574                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18575                if (userInfo == null) {
18576                    Slog.w(TAG, "No user info for user #" + userId);
18577                    return false;
18578                }
18579                if (foreground && userInfo.isManagedProfile()) {
18580                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18581                    return false;
18582                }
18583
18584                if (foreground) {
18585                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18586                            R.anim.screen_user_enter);
18587                }
18588
18589                boolean needStart = false;
18590
18591                // If the user we are switching to is not currently started, then
18592                // we need to start it now.
18593                if (mStartedUsers.get(userId) == null) {
18594                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18595                    updateStartedUserArrayLocked();
18596                    needStart = true;
18597                }
18598
18599                final Integer userIdInt = Integer.valueOf(userId);
18600                mUserLru.remove(userIdInt);
18601                mUserLru.add(userIdInt);
18602
18603                if (foreground) {
18604                    mCurrentUserId = userId;
18605                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18606                    updateCurrentProfileIdsLocked();
18607                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18608                    // Once the internal notion of the active user has switched, we lock the device
18609                    // with the option to show the user switcher on the keyguard.
18610                    mWindowManager.lockNow(null);
18611                } else {
18612                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18613                    updateCurrentProfileIdsLocked();
18614                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18615                    mUserLru.remove(currentUserIdInt);
18616                    mUserLru.add(currentUserIdInt);
18617                }
18618
18619                final UserStartedState uss = mStartedUsers.get(userId);
18620
18621                // Make sure user is in the started state.  If it is currently
18622                // stopping, we need to knock that off.
18623                if (uss.mState == UserStartedState.STATE_STOPPING) {
18624                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18625                    // so we can just fairly silently bring the user back from
18626                    // the almost-dead.
18627                    uss.mState = UserStartedState.STATE_RUNNING;
18628                    updateStartedUserArrayLocked();
18629                    needStart = true;
18630                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18631                    // This means ACTION_SHUTDOWN has been sent, so we will
18632                    // need to treat this as a new boot of the user.
18633                    uss.mState = UserStartedState.STATE_BOOTING;
18634                    updateStartedUserArrayLocked();
18635                    needStart = true;
18636                }
18637
18638                if (uss.mState == UserStartedState.STATE_BOOTING) {
18639                    // Booting up a new user, need to tell system services about it.
18640                    // Note that this is on the same handler as scheduling of broadcasts,
18641                    // which is important because it needs to go first.
18642                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18643                }
18644
18645                if (foreground) {
18646                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18647                            oldUserId));
18648                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18649                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18650                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18651                            oldUserId, userId, uss));
18652                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18653                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18654                }
18655
18656                if (needStart) {
18657                    // Send USER_STARTED broadcast
18658                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18659                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18660                            | Intent.FLAG_RECEIVER_FOREGROUND);
18661                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18662                    broadcastIntentLocked(null, null, intent,
18663                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18664                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18665                }
18666
18667                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18668                    if (userId != UserHandle.USER_OWNER) {
18669                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18670                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18671                        broadcastIntentLocked(null, null, intent, null,
18672                                new IIntentReceiver.Stub() {
18673                                    public void performReceive(Intent intent, int resultCode,
18674                                            String data, Bundle extras, boolean ordered,
18675                                            boolean sticky, int sendingUser) {
18676                                        onUserInitialized(uss, foreground, oldUserId, userId);
18677                                    }
18678                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18679                                true, false, MY_PID, Process.SYSTEM_UID,
18680                                userId);
18681                        uss.initializing = true;
18682                    } else {
18683                        getUserManagerLocked().makeInitialized(userInfo.id);
18684                    }
18685                }
18686
18687                if (foreground) {
18688                    if (!uss.initializing) {
18689                        moveUserToForeground(uss, oldUserId, userId);
18690                    }
18691                } else {
18692                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18693                }
18694
18695                if (needStart) {
18696                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18697                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18698                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18699                    broadcastIntentLocked(null, null, intent,
18700                            null, new IIntentReceiver.Stub() {
18701                                @Override
18702                                public void performReceive(Intent intent, int resultCode, String data,
18703                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18704                                        throws RemoteException {
18705                                }
18706                            }, 0, null, null,
18707                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18708                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18709                }
18710            }
18711        } finally {
18712            Binder.restoreCallingIdentity(ident);
18713        }
18714
18715        return true;
18716    }
18717
18718    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18719        long ident = Binder.clearCallingIdentity();
18720        try {
18721            Intent intent;
18722            if (oldUserId >= 0) {
18723                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18724                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18725                int count = profiles.size();
18726                for (int i = 0; i < count; i++) {
18727                    int profileUserId = profiles.get(i).id;
18728                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18729                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18730                            | Intent.FLAG_RECEIVER_FOREGROUND);
18731                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18732                    broadcastIntentLocked(null, null, intent,
18733                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18734                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18735                }
18736            }
18737            if (newUserId >= 0) {
18738                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18739                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18740                int count = profiles.size();
18741                for (int i = 0; i < count; i++) {
18742                    int profileUserId = profiles.get(i).id;
18743                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18744                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18745                            | Intent.FLAG_RECEIVER_FOREGROUND);
18746                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18747                    broadcastIntentLocked(null, null, intent,
18748                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18749                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18750                }
18751                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18752                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18753                        | Intent.FLAG_RECEIVER_FOREGROUND);
18754                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18755                broadcastIntentLocked(null, null, intent,
18756                        null, null, 0, null, null,
18757                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18758                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18759            }
18760        } finally {
18761            Binder.restoreCallingIdentity(ident);
18762        }
18763    }
18764
18765    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18766            final int newUserId) {
18767        final int N = mUserSwitchObservers.beginBroadcast();
18768        if (N > 0) {
18769            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18770                int mCount = 0;
18771                @Override
18772                public void sendResult(Bundle data) throws RemoteException {
18773                    synchronized (ActivityManagerService.this) {
18774                        if (mCurUserSwitchCallback == this) {
18775                            mCount++;
18776                            if (mCount == N) {
18777                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18778                            }
18779                        }
18780                    }
18781                }
18782            };
18783            synchronized (this) {
18784                uss.switching = true;
18785                mCurUserSwitchCallback = callback;
18786            }
18787            for (int i=0; i<N; i++) {
18788                try {
18789                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18790                            newUserId, callback);
18791                } catch (RemoteException e) {
18792                }
18793            }
18794        } else {
18795            synchronized (this) {
18796                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18797            }
18798        }
18799        mUserSwitchObservers.finishBroadcast();
18800    }
18801
18802    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18803        synchronized (this) {
18804            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18805            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18806        }
18807    }
18808
18809    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18810        mCurUserSwitchCallback = null;
18811        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18812        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18813                oldUserId, newUserId, uss));
18814    }
18815
18816    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18817        synchronized (this) {
18818            if (foreground) {
18819                moveUserToForeground(uss, oldUserId, newUserId);
18820            }
18821        }
18822
18823        completeSwitchAndInitalize(uss, newUserId, true, false);
18824    }
18825
18826    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18827        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18828        if (homeInFront) {
18829            startHomeActivityLocked(newUserId);
18830        } else {
18831            mStackSupervisor.resumeTopActivitiesLocked();
18832        }
18833        EventLogTags.writeAmSwitchUser(newUserId);
18834        getUserManagerLocked().userForeground(newUserId);
18835        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18836    }
18837
18838    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18839        completeSwitchAndInitalize(uss, newUserId, false, true);
18840    }
18841
18842    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18843            boolean clearInitializing, boolean clearSwitching) {
18844        boolean unfrozen = false;
18845        synchronized (this) {
18846            if (clearInitializing) {
18847                uss.initializing = false;
18848                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18849            }
18850            if (clearSwitching) {
18851                uss.switching = false;
18852            }
18853            if (!uss.switching && !uss.initializing) {
18854                mWindowManager.stopFreezingScreen();
18855                unfrozen = true;
18856            }
18857        }
18858        if (unfrozen) {
18859            final int N = mUserSwitchObservers.beginBroadcast();
18860            for (int i=0; i<N; i++) {
18861                try {
18862                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18863                } catch (RemoteException e) {
18864                }
18865            }
18866            mUserSwitchObservers.finishBroadcast();
18867        }
18868    }
18869
18870    void scheduleStartProfilesLocked() {
18871        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18872            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18873                    DateUtils.SECOND_IN_MILLIS);
18874        }
18875    }
18876
18877    void startProfilesLocked() {
18878        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18879        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18880                mCurrentUserId, false /* enabledOnly */);
18881        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18882        for (UserInfo user : profiles) {
18883            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18884                    && user.id != mCurrentUserId) {
18885                toStart.add(user);
18886            }
18887        }
18888        final int n = toStart.size();
18889        int i = 0;
18890        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18891            startUserInBackground(toStart.get(i).id);
18892        }
18893        if (i < n) {
18894            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18895        }
18896    }
18897
18898    void finishUserBoot(UserStartedState uss) {
18899        synchronized (this) {
18900            if (uss.mState == UserStartedState.STATE_BOOTING
18901                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18902                uss.mState = UserStartedState.STATE_RUNNING;
18903                final int userId = uss.mHandle.getIdentifier();
18904                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18905                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18906                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18907                broadcastIntentLocked(null, null, intent,
18908                        null, null, 0, null, null,
18909                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18910                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18911            }
18912        }
18913    }
18914
18915    void finishUserSwitch(UserStartedState uss) {
18916        synchronized (this) {
18917            finishUserBoot(uss);
18918
18919            startProfilesLocked();
18920
18921            int num = mUserLru.size();
18922            int i = 0;
18923            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18924                Integer oldUserId = mUserLru.get(i);
18925                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18926                if (oldUss == null) {
18927                    // Shouldn't happen, but be sane if it does.
18928                    mUserLru.remove(i);
18929                    num--;
18930                    continue;
18931                }
18932                if (oldUss.mState == UserStartedState.STATE_STOPPING
18933                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18934                    // This user is already stopping, doesn't count.
18935                    num--;
18936                    i++;
18937                    continue;
18938                }
18939                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18940                    // Owner and current can't be stopped, but count as running.
18941                    i++;
18942                    continue;
18943                }
18944                // This is a user to be stopped.
18945                stopUserLocked(oldUserId, null);
18946                num--;
18947                i++;
18948            }
18949        }
18950    }
18951
18952    @Override
18953    public int stopUser(final int userId, final IStopUserCallback callback) {
18954        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18955                != PackageManager.PERMISSION_GRANTED) {
18956            String msg = "Permission Denial: switchUser() from pid="
18957                    + Binder.getCallingPid()
18958                    + ", uid=" + Binder.getCallingUid()
18959                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18960            Slog.w(TAG, msg);
18961            throw new SecurityException(msg);
18962        }
18963        if (userId <= 0) {
18964            throw new IllegalArgumentException("Can't stop primary user " + userId);
18965        }
18966        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18967        synchronized (this) {
18968            return stopUserLocked(userId, callback);
18969        }
18970    }
18971
18972    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18973        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18974        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18975            return ActivityManager.USER_OP_IS_CURRENT;
18976        }
18977
18978        final UserStartedState uss = mStartedUsers.get(userId);
18979        if (uss == null) {
18980            // User is not started, nothing to do...  but we do need to
18981            // callback if requested.
18982            if (callback != null) {
18983                mHandler.post(new Runnable() {
18984                    @Override
18985                    public void run() {
18986                        try {
18987                            callback.userStopped(userId);
18988                        } catch (RemoteException e) {
18989                        }
18990                    }
18991                });
18992            }
18993            return ActivityManager.USER_OP_SUCCESS;
18994        }
18995
18996        if (callback != null) {
18997            uss.mStopCallbacks.add(callback);
18998        }
18999
19000        if (uss.mState != UserStartedState.STATE_STOPPING
19001                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19002            uss.mState = UserStartedState.STATE_STOPPING;
19003            updateStartedUserArrayLocked();
19004
19005            long ident = Binder.clearCallingIdentity();
19006            try {
19007                // We are going to broadcast ACTION_USER_STOPPING and then
19008                // once that is done send a final ACTION_SHUTDOWN and then
19009                // stop the user.
19010                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19011                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19012                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19013                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19014                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19015                // This is the result receiver for the final shutdown broadcast.
19016                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19017                    @Override
19018                    public void performReceive(Intent intent, int resultCode, String data,
19019                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19020                        finishUserStop(uss);
19021                    }
19022                };
19023                // This is the result receiver for the initial stopping broadcast.
19024                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19025                    @Override
19026                    public void performReceive(Intent intent, int resultCode, String data,
19027                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19028                        // On to the next.
19029                        synchronized (ActivityManagerService.this) {
19030                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19031                                // Whoops, we are being started back up.  Abort, abort!
19032                                return;
19033                            }
19034                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19035                        }
19036                        mBatteryStatsService.noteEvent(
19037                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19038                                Integer.toString(userId), userId);
19039                        mSystemServiceManager.stopUser(userId);
19040                        broadcastIntentLocked(null, null, shutdownIntent,
19041                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19042                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19043                    }
19044                };
19045                // Kick things off.
19046                broadcastIntentLocked(null, null, stoppingIntent,
19047                        null, stoppingReceiver, 0, null, null,
19048                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19049                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19050            } finally {
19051                Binder.restoreCallingIdentity(ident);
19052            }
19053        }
19054
19055        return ActivityManager.USER_OP_SUCCESS;
19056    }
19057
19058    void finishUserStop(UserStartedState uss) {
19059        final int userId = uss.mHandle.getIdentifier();
19060        boolean stopped;
19061        ArrayList<IStopUserCallback> callbacks;
19062        synchronized (this) {
19063            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19064            if (mStartedUsers.get(userId) != uss) {
19065                stopped = false;
19066            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19067                stopped = false;
19068            } else {
19069                stopped = true;
19070                // User can no longer run.
19071                mStartedUsers.remove(userId);
19072                mUserLru.remove(Integer.valueOf(userId));
19073                updateStartedUserArrayLocked();
19074
19075                // Clean up all state and processes associated with the user.
19076                // Kill all the processes for the user.
19077                forceStopUserLocked(userId, "finish user");
19078            }
19079
19080            // Explicitly remove the old information in mRecentTasks.
19081            removeRecentTasksForUserLocked(userId);
19082        }
19083
19084        for (int i=0; i<callbacks.size(); i++) {
19085            try {
19086                if (stopped) callbacks.get(i).userStopped(userId);
19087                else callbacks.get(i).userStopAborted(userId);
19088            } catch (RemoteException e) {
19089            }
19090        }
19091
19092        if (stopped) {
19093            mSystemServiceManager.cleanupUser(userId);
19094            synchronized (this) {
19095                mStackSupervisor.removeUserLocked(userId);
19096            }
19097        }
19098    }
19099
19100    @Override
19101    public UserInfo getCurrentUser() {
19102        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19103                != PackageManager.PERMISSION_GRANTED) && (
19104                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19105                != PackageManager.PERMISSION_GRANTED)) {
19106            String msg = "Permission Denial: getCurrentUser() from pid="
19107                    + Binder.getCallingPid()
19108                    + ", uid=" + Binder.getCallingUid()
19109                    + " requires " + INTERACT_ACROSS_USERS;
19110            Slog.w(TAG, msg);
19111            throw new SecurityException(msg);
19112        }
19113        synchronized (this) {
19114            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19115            return getUserManagerLocked().getUserInfo(userId);
19116        }
19117    }
19118
19119    int getCurrentUserIdLocked() {
19120        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19121    }
19122
19123    @Override
19124    public boolean isUserRunning(int userId, boolean orStopped) {
19125        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19126                != PackageManager.PERMISSION_GRANTED) {
19127            String msg = "Permission Denial: isUserRunning() from pid="
19128                    + Binder.getCallingPid()
19129                    + ", uid=" + Binder.getCallingUid()
19130                    + " requires " + INTERACT_ACROSS_USERS;
19131            Slog.w(TAG, msg);
19132            throw new SecurityException(msg);
19133        }
19134        synchronized (this) {
19135            return isUserRunningLocked(userId, orStopped);
19136        }
19137    }
19138
19139    boolean isUserRunningLocked(int userId, boolean orStopped) {
19140        UserStartedState state = mStartedUsers.get(userId);
19141        if (state == null) {
19142            return false;
19143        }
19144        if (orStopped) {
19145            return true;
19146        }
19147        return state.mState != UserStartedState.STATE_STOPPING
19148                && state.mState != UserStartedState.STATE_SHUTDOWN;
19149    }
19150
19151    @Override
19152    public int[] getRunningUserIds() {
19153        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19154                != PackageManager.PERMISSION_GRANTED) {
19155            String msg = "Permission Denial: isUserRunning() from pid="
19156                    + Binder.getCallingPid()
19157                    + ", uid=" + Binder.getCallingUid()
19158                    + " requires " + INTERACT_ACROSS_USERS;
19159            Slog.w(TAG, msg);
19160            throw new SecurityException(msg);
19161        }
19162        synchronized (this) {
19163            return mStartedUserArray;
19164        }
19165    }
19166
19167    private void updateStartedUserArrayLocked() {
19168        int num = 0;
19169        for (int i=0; i<mStartedUsers.size();  i++) {
19170            UserStartedState uss = mStartedUsers.valueAt(i);
19171            // This list does not include stopping users.
19172            if (uss.mState != UserStartedState.STATE_STOPPING
19173                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19174                num++;
19175            }
19176        }
19177        mStartedUserArray = new int[num];
19178        num = 0;
19179        for (int i=0; i<mStartedUsers.size();  i++) {
19180            UserStartedState uss = mStartedUsers.valueAt(i);
19181            if (uss.mState != UserStartedState.STATE_STOPPING
19182                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19183                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19184                num++;
19185            }
19186        }
19187    }
19188
19189    @Override
19190    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19191        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19192                != PackageManager.PERMISSION_GRANTED) {
19193            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19194                    + Binder.getCallingPid()
19195                    + ", uid=" + Binder.getCallingUid()
19196                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19197            Slog.w(TAG, msg);
19198            throw new SecurityException(msg);
19199        }
19200
19201        mUserSwitchObservers.register(observer);
19202    }
19203
19204    @Override
19205    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19206        mUserSwitchObservers.unregister(observer);
19207    }
19208
19209    private boolean userExists(int userId) {
19210        if (userId == 0) {
19211            return true;
19212        }
19213        UserManagerService ums = getUserManagerLocked();
19214        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19215    }
19216
19217    int[] getUsersLocked() {
19218        UserManagerService ums = getUserManagerLocked();
19219        return ums != null ? ums.getUserIds() : new int[] { 0 };
19220    }
19221
19222    UserManagerService getUserManagerLocked() {
19223        if (mUserManager == null) {
19224            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19225            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19226        }
19227        return mUserManager;
19228    }
19229
19230    private int applyUserId(int uid, int userId) {
19231        return UserHandle.getUid(userId, uid);
19232    }
19233
19234    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19235        if (info == null) return null;
19236        ApplicationInfo newInfo = new ApplicationInfo(info);
19237        newInfo.uid = applyUserId(info.uid, userId);
19238        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19239                + info.packageName;
19240        return newInfo;
19241    }
19242
19243    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19244        if (aInfo == null
19245                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19246            return aInfo;
19247        }
19248
19249        ActivityInfo info = new ActivityInfo(aInfo);
19250        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19251        return info;
19252    }
19253
19254    private final class LocalService extends ActivityManagerInternal {
19255        @Override
19256        public void onWakefulnessChanged(int wakefulness) {
19257            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19258        }
19259
19260        @Override
19261        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19262                String processName, String abiOverride, int uid, Runnable crashHandler) {
19263            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19264                    processName, abiOverride, uid, crashHandler);
19265        }
19266    }
19267
19268    /**
19269     * An implementation of IAppTask, that allows an app to manage its own tasks via
19270     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19271     * only the process that calls getAppTasks() can call the AppTask methods.
19272     */
19273    class AppTaskImpl extends IAppTask.Stub {
19274        private int mTaskId;
19275        private int mCallingUid;
19276
19277        public AppTaskImpl(int taskId, int callingUid) {
19278            mTaskId = taskId;
19279            mCallingUid = callingUid;
19280        }
19281
19282        private void checkCaller() {
19283            if (mCallingUid != Binder.getCallingUid()) {
19284                throw new SecurityException("Caller " + mCallingUid
19285                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19286            }
19287        }
19288
19289        @Override
19290        public void finishAndRemoveTask() {
19291            checkCaller();
19292
19293            synchronized (ActivityManagerService.this) {
19294                long origId = Binder.clearCallingIdentity();
19295                try {
19296                    if (!removeTaskByIdLocked(mTaskId, false)) {
19297                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19298                    }
19299                } finally {
19300                    Binder.restoreCallingIdentity(origId);
19301                }
19302            }
19303        }
19304
19305        @Override
19306        public ActivityManager.RecentTaskInfo getTaskInfo() {
19307            checkCaller();
19308
19309            synchronized (ActivityManagerService.this) {
19310                long origId = Binder.clearCallingIdentity();
19311                try {
19312                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19313                    if (tr == null) {
19314                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19315                    }
19316                    return createRecentTaskInfoFromTaskRecord(tr);
19317                } finally {
19318                    Binder.restoreCallingIdentity(origId);
19319                }
19320            }
19321        }
19322
19323        @Override
19324        public void moveToFront() {
19325            checkCaller();
19326
19327            final TaskRecord tr;
19328            synchronized (ActivityManagerService.this) {
19329                tr = recentTaskForIdLocked(mTaskId);
19330                if (tr == null) {
19331                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19332                }
19333                if (tr.getRootActivity() != null) {
19334                    moveTaskToFrontLocked(tr.taskId, 0, null);
19335                    return;
19336                }
19337            }
19338
19339            startActivityFromRecentsInner(tr.taskId, null);
19340        }
19341
19342        @Override
19343        public int startActivity(IBinder whoThread, String callingPackage,
19344                Intent intent, String resolvedType, Bundle options) {
19345            checkCaller();
19346
19347            int callingUser = UserHandle.getCallingUserId();
19348            TaskRecord tr;
19349            IApplicationThread appThread;
19350            synchronized (ActivityManagerService.this) {
19351                tr = recentTaskForIdLocked(mTaskId);
19352                if (tr == null) {
19353                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19354                }
19355                appThread = ApplicationThreadNative.asInterface(whoThread);
19356                if (appThread == null) {
19357                    throw new IllegalArgumentException("Bad app thread " + appThread);
19358                }
19359            }
19360            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19361                    resolvedType, null, null, null, null, 0, 0, null, null,
19362                    null, options, callingUser, null, tr);
19363        }
19364
19365        @Override
19366        public void setExcludeFromRecents(boolean exclude) {
19367            checkCaller();
19368
19369            synchronized (ActivityManagerService.this) {
19370                long origId = Binder.clearCallingIdentity();
19371                try {
19372                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19373                    if (tr == null) {
19374                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19375                    }
19376                    Intent intent = tr.getBaseIntent();
19377                    if (exclude) {
19378                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19379                    } else {
19380                        intent.setFlags(intent.getFlags()
19381                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19382                    }
19383                } finally {
19384                    Binder.restoreCallingIdentity(origId);
19385                }
19386            }
19387        }
19388    }
19389}
19390