ActivityManagerService.java revision 11cce7989b41be88bb81af072bc9bed7ab829694
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.ActivityManagerDebugConfig.*;
34import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
35
36import android.Manifest;
37import android.app.AppOpsManager;
38import android.app.ApplicationThreadNative;
39import android.app.IActivityContainer;
40import android.app.IActivityContainerCallback;
41import android.app.IAppTask;
42import android.app.ITaskStackListener;
43import android.app.ProfilerInfo;
44import android.app.admin.DevicePolicyManager;
45import android.app.usage.UsageEvents;
46import android.app.usage.UsageStatsManagerInternal;
47import android.appwidget.AppWidgetManager;
48import android.content.res.Resources;
49import android.graphics.Bitmap;
50import android.graphics.Point;
51import android.graphics.Rect;
52import android.os.BatteryStats;
53import android.os.PersistableBundle;
54import android.os.storage.IMountService;
55import android.os.storage.StorageManager;
56import android.service.voice.IVoiceInteractionSession;
57import android.util.ArrayMap;
58import android.util.ArraySet;
59import android.util.DebugUtils;
60import android.util.SparseIntArray;
61
62import android.view.Display;
63import com.android.internal.R;
64import com.android.internal.annotations.GuardedBy;
65import com.android.internal.app.DumpHeapActivity;
66import com.android.internal.app.IAppOpsService;
67import com.android.internal.app.IVoiceInteractor;
68import com.android.internal.app.ProcessMap;
69import com.android.internal.app.ProcessStats;
70import com.android.internal.os.BackgroundThread;
71import com.android.internal.os.BatteryStatsImpl;
72import com.android.internal.os.IResultReceiver;
73import com.android.internal.os.ProcessCpuTracker;
74import com.android.internal.os.TransferPipe;
75import com.android.internal.os.Zygote;
76import com.android.internal.util.FastPrintWriter;
77import com.android.internal.util.FastXmlSerializer;
78import com.android.internal.util.MemInfoReader;
79import com.android.internal.util.Preconditions;
80import com.android.server.AppOpsService;
81import com.android.server.AttributeCache;
82import com.android.server.IntentResolver;
83import com.android.server.LocalServices;
84import com.android.server.ServiceThread;
85import com.android.server.SystemService;
86import com.android.server.SystemServiceManager;
87import com.android.server.Watchdog;
88import com.android.server.am.ActivityStack.ActivityState;
89import com.android.server.firewall.IntentFirewall;
90import com.android.server.pm.Installer;
91import com.android.server.pm.UserManagerService;
92import com.android.server.statusbar.StatusBarManagerInternal;
93import com.android.server.wm.AppTransition;
94import com.android.server.wm.WindowManagerService;
95
96import com.google.android.collect.Lists;
97import com.google.android.collect.Maps;
98
99import libcore.io.IoUtils;
100
101import org.xmlpull.v1.XmlPullParser;
102import org.xmlpull.v1.XmlPullParserException;
103import org.xmlpull.v1.XmlSerializer;
104
105import android.app.Activity;
106import android.app.ActivityManager;
107import android.app.ActivityManager.RunningTaskInfo;
108import android.app.ActivityManager.StackInfo;
109import android.app.ActivityManagerInternal;
110import android.app.ActivityManagerNative;
111import android.app.ActivityOptions;
112import android.app.ActivityThread;
113import android.app.AlertDialog;
114import android.app.AppGlobals;
115import android.app.ApplicationErrorReport;
116import android.app.Dialog;
117import android.app.IActivityController;
118import android.app.IApplicationThread;
119import android.app.IInstrumentationWatcher;
120import android.app.INotificationManager;
121import android.app.IProcessObserver;
122import android.app.IServiceConnection;
123import android.app.IStopUserCallback;
124import android.app.IUiAutomationConnection;
125import android.app.IUserSwitchObserver;
126import android.app.Instrumentation;
127import android.app.Notification;
128import android.app.NotificationManager;
129import android.app.PendingIntent;
130import android.app.backup.IBackupManager;
131import android.content.ActivityNotFoundException;
132import android.content.BroadcastReceiver;
133import android.content.ClipData;
134import android.content.ComponentCallbacks2;
135import android.content.ComponentName;
136import android.content.ContentProvider;
137import android.content.ContentResolver;
138import android.content.Context;
139import android.content.DialogInterface;
140import android.content.IContentProvider;
141import android.content.IIntentReceiver;
142import android.content.IIntentSender;
143import android.content.Intent;
144import android.content.IntentFilter;
145import android.content.IntentSender;
146import android.content.pm.ActivityInfo;
147import android.content.pm.ApplicationInfo;
148import android.content.pm.ConfigurationInfo;
149import android.content.pm.IPackageDataObserver;
150import android.content.pm.IPackageManager;
151import android.content.pm.InstrumentationInfo;
152import android.content.pm.PackageInfo;
153import android.content.pm.PackageManager;
154import android.content.pm.ParceledListSlice;
155import android.content.pm.UserInfo;
156import android.content.pm.PackageManager.NameNotFoundException;
157import android.content.pm.PathPermission;
158import android.content.pm.ProviderInfo;
159import android.content.pm.ResolveInfo;
160import android.content.pm.ServiceInfo;
161import android.content.res.CompatibilityInfo;
162import android.content.res.Configuration;
163import android.net.Proxy;
164import android.net.ProxyInfo;
165import android.net.Uri;
166import android.os.Binder;
167import android.os.Build;
168import android.os.Bundle;
169import android.os.Debug;
170import android.os.DropBoxManager;
171import android.os.Environment;
172import android.os.FactoryTest;
173import android.os.FileObserver;
174import android.os.FileUtils;
175import android.os.Handler;
176import android.os.IBinder;
177import android.os.IPermissionController;
178import android.os.IProcessInfoService;
179import android.os.IRemoteCallback;
180import android.os.IUserManager;
181import android.os.Looper;
182import android.os.Message;
183import android.os.Parcel;
184import android.os.ParcelFileDescriptor;
185import android.os.PowerManagerInternal;
186import android.os.Process;
187import android.os.RemoteCallbackList;
188import android.os.RemoteException;
189import android.os.SELinux;
190import android.os.ServiceManager;
191import android.os.StrictMode;
192import android.os.SystemClock;
193import android.os.SystemProperties;
194import android.os.UpdateLock;
195import android.os.UserHandle;
196import android.os.UserManager;
197import android.provider.Settings;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.AtomicFile;
201import android.util.EventLog;
202import android.util.Log;
203import android.util.Pair;
204import android.util.PrintWriterPrinter;
205import android.util.Slog;
206import android.util.SparseArray;
207import android.util.TimeUtils;
208import android.util.Xml;
209import android.view.Gravity;
210import android.view.LayoutInflater;
211import android.view.View;
212import android.view.WindowManager;
213
214import dalvik.system.VMRuntime;
215
216import java.io.BufferedInputStream;
217import java.io.BufferedOutputStream;
218import java.io.DataInputStream;
219import java.io.DataOutputStream;
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244public final class ActivityManagerService extends ActivityManagerNative
245        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
246
247    private static final String USER_DATA_DIR = "/data/user/";
248    // File that stores last updated system version and called preboot receivers
249    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
250
251    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
252    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
253    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
254    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
255    private static final String TAG_MU = TAG + POSTFIX_MU;
256
257    // TODO(ogunwale): Migrate all the constants below to use ActivityManagerDebugConfig class.
258    static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
259    static final boolean DEBUG_FOCUS = false;
260    static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
261    static final boolean DEBUG_MU = DEBUG_ALL || false;
262    static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
263    static final boolean DEBUG_LRU = DEBUG_ALL || false;
264    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
265    static final boolean DEBUG_POWER = DEBUG_ALL || false;
266    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
267    static final boolean DEBUG_PROCESS_OBSERVERS = DEBUG_ALL || false;
268    static final boolean DEBUG_PROCESSES = DEBUG_ALL || false;
269    static final boolean DEBUG_PROVIDER = DEBUG_ALL || false;
270    static final boolean DEBUG_RESULTS = DEBUG_ALL || false;
271    static final boolean DEBUG_SERVICE = DEBUG_ALL || false;
272    static final boolean DEBUG_SERVICE_EXECUTING = DEBUG_ALL || false;
273    static final boolean DEBUG_STACK = DEBUG_ALL || false;
274    static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
275    static final boolean DEBUG_TASKS = DEBUG_ALL || false;
276    static final boolean DEBUG_THUMBNAILS = DEBUG_ALL || false;
277    static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
278    static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
279    static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
280    static final boolean DEBUG_VISBILITY = DEBUG_ALL || false;
281    static final boolean DEBUG_PSS = DEBUG_ALL || false;
282    static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
283    static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
284    static final boolean VALIDATE_TOKENS = false;
285    static final boolean SHOW_ACTIVITY_START_TIME = true;
286
287    // Control over CPU and battery monitoring.
288    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
289    static final boolean MONITOR_CPU_USAGE = true;
290    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
291    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
292    static final boolean MONITOR_THREAD_CPU_USAGE = false;
293
294    // The flags that are set for all calls we make to the package manager.
295    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
296
297    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
298
299    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
300
301    // Amount of time after a call to stopAppSwitches() during which we will
302    // prevent further untrusted switches from happening.
303    static final long APP_SWITCH_DELAY_TIME = 5*1000;
304
305    // How long we wait for a launched process to attach to the activity manager
306    // before we decide it's never going to come up for real.
307    static final int PROC_START_TIMEOUT = 10*1000;
308
309    // How long we wait for a launched process to attach to the activity manager
310    // before we decide it's never going to come up for real, when the process was
311    // started with a wrapper for instrumentation (such as Valgrind) because it
312    // could take much longer than usual.
313    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
314
315    // How long to wait after going idle before forcing apps to GC.
316    static final int GC_TIMEOUT = 5*1000;
317
318    // The minimum amount of time between successive GC requests for a process.
319    static final int GC_MIN_INTERVAL = 60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process.
322    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
323
324    // The minimum amount of time between successive PSS requests for a process
325    // when the request is due to the memory state being lowered.
326    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
327
328    // The rate at which we check for apps using excessive power -- 15 mins.
329    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
330
331    // The minimum sample duration we will allow before deciding we have
332    // enough data on wake locks to start killing things.
333    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335    // The minimum sample duration we will allow before deciding we have
336    // enough data on CPU usage to start killing things.
337    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
338
339    // How long we allow a receiver to run before giving up on it.
340    static final int BROADCAST_FG_TIMEOUT = 10*1000;
341    static final int BROADCAST_BG_TIMEOUT = 60*1000;
342
343    // How long we wait until we timeout on key dispatching.
344    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
345
346    // How long we wait until we timeout on key dispatching during instrumentation.
347    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
348
349    // Amount of time we wait for observers to handle a user switch before
350    // giving up on them and unfreezing the screen.
351    static final int USER_SWITCH_TIMEOUT = 2*1000;
352
353    // Maximum number of users we allow to be running at a time.
354    static final int MAX_RUNNING_USERS = 3;
355
356    // How long to wait in getAssistContextExtras for the activity and foreground services
357    // to respond with the result.
358    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
359
360    // Maximum number of persisted Uri grants a package is allowed
361    static final int MAX_PERSISTED_URI_GRANTS = 128;
362
363    static final int MY_PID = Process.myPid();
364
365    static final String[] EMPTY_STRING_ARRAY = new String[0];
366
367    // How many bytes to write into the dropbox log before truncating
368    static final int DROPBOX_MAX_SIZE = 256 * 1024;
369
370    // Access modes for handleIncomingUser.
371    static final int ALLOW_NON_FULL = 0;
372    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
373    static final int ALLOW_FULL_ONLY = 2;
374
375    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
376
377    // Delay in notifying task stack change listeners (in millis)
378    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
379
380    /** All system services */
381    SystemServiceManager mSystemServiceManager;
382
383    private Installer mInstaller;
384
385    /** Run all ActivityStacks through this */
386    ActivityStackSupervisor mStackSupervisor;
387
388    /** Task stack change listeners. */
389    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
390            new RemoteCallbackList<ITaskStackListener>();
391
392    public IntentFirewall mIntentFirewall;
393
394    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
395    // default actuion automatically.  Important for devices without direct input
396    // devices.
397    private boolean mShowDialogs = true;
398
399    BroadcastQueue mFgBroadcastQueue;
400    BroadcastQueue mBgBroadcastQueue;
401    // Convenient for easy iteration over the queues. Foreground is first
402    // so that dispatch of foreground broadcasts gets precedence.
403    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
404
405    BroadcastQueue broadcastQueueForIntent(Intent intent) {
406        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
407        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
408                "Broadcast intent " + intent + " on "
409                + (isFg ? "foreground" : "background") + " queue");
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    private final RecentTasks mRecentTasks;
422
423    /**
424     * For addAppTask: cached of the last activity component that was added.
425     */
426    ComponentName mLastAddedTaskComponent;
427
428    /**
429     * For addAppTask: cached of the last activity uid that was added.
430     */
431    int mLastAddedTaskUid;
432
433    /**
434     * For addAppTask: cached of the last ActivityInfo that was added.
435     */
436    ActivityInfo mLastAddedTaskActivity;
437
438    public class PendingAssistExtras extends Binder implements Runnable {
439        public final ActivityRecord activity;
440        public final Bundle extras;
441        public final Intent intent;
442        public final String hint;
443        public final IResultReceiver receiver;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, IResultReceiver _receiver, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            receiver = _receiver;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (ActivityManagerService.this) {
460                synchronized (this) {
461                    haveResult = true;
462                    notifyAll();
463                }
464                pendingAssistExtrasTimedOutLocked(this);
465            }
466        }
467    }
468
469    final ArrayList<PendingAssistExtras> mPendingAssistExtras
470            = new ArrayList<PendingAssistExtras>();
471
472    /**
473     * Process management.
474     */
475    final ProcessList mProcessList = new ProcessList();
476
477    /**
478     * All of the applications we currently have running organized by name.
479     * The keys are strings of the application package name (as
480     * returned by the package manager), and the keys are ApplicationRecord
481     * objects.
482     */
483    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
484
485    /**
486     * Tracking long-term execution of processes to look for abuse and other
487     * bad app behavior.
488     */
489    final ProcessStatsService mProcessStats;
490
491    /**
492     * The currently running isolated processes.
493     */
494    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
495
496    /**
497     * Counter for assigning isolated process uids, to avoid frequently reusing the
498     * same ones.
499     */
500    int mNextIsolatedProcessUid = 0;
501
502    /**
503     * The currently running heavy-weight process, if any.
504     */
505    ProcessRecord mHeavyWeightProcess = null;
506
507    /**
508     * The last time that various processes have crashed.
509     */
510    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
511
512    /**
513     * Information about a process that is currently marked as bad.
514     */
515    static final class BadProcessInfo {
516        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
517            this.time = time;
518            this.shortMsg = shortMsg;
519            this.longMsg = longMsg;
520            this.stack = stack;
521        }
522
523        final long time;
524        final String shortMsg;
525        final String longMsg;
526        final String stack;
527    }
528
529    /**
530     * Set of applications that we consider to be bad, and will reject
531     * incoming broadcasts from (which the user has no control over).
532     * Processes are added to this set when they have crashed twice within
533     * a minimum amount of time; they are removed from it when they are
534     * later restarted (hopefully due to some user action).  The value is the
535     * time it was added to the list.
536     */
537    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
538
539    /**
540     * All of the processes we currently have running organized by pid.
541     * The keys are the pid running the application.
542     *
543     * <p>NOTE: This object is protected by its own lock, NOT the global
544     * activity manager lock!
545     */
546    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
547
548    /**
549     * All of the processes that have been forced to be foreground.  The key
550     * is the pid of the caller who requested it (we hold a death
551     * link on it).
552     */
553    abstract class ForegroundToken implements IBinder.DeathRecipient {
554        int pid;
555        IBinder token;
556    }
557    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
558
559    /**
560     * List of records for processes that someone had tried to start before the
561     * system was ready.  We don't start them at that point, but ensure they
562     * are started by the time booting is complete.
563     */
564    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
565
566    /**
567     * List of persistent applications that are in the process
568     * of being started.
569     */
570    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
571
572    /**
573     * Processes that are being forcibly torn down.
574     */
575    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * List of running applications, sorted by recent usage.
579     * The first entry in the list is the least recently used.
580     */
581    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Where in mLruProcesses that the processes hosting activities start.
585     */
586    int mLruProcessActivityStart = 0;
587
588    /**
589     * Where in mLruProcesses that the processes hosting services start.
590     * This is after (lower index) than mLruProcessesActivityStart.
591     */
592    int mLruProcessServiceStart = 0;
593
594    /**
595     * List of processes that should gc as soon as things are idle.
596     */
597    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
598
599    /**
600     * Processes we want to collect PSS data from.
601     */
602    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
603
604    /**
605     * Last time we requested PSS data of all processes.
606     */
607    long mLastFullPssTime = SystemClock.uptimeMillis();
608
609    /**
610     * If set, the next time we collect PSS data we should do a full collection
611     * with data from native processes and the kernel.
612     */
613    boolean mFullPssPending = false;
614
615    /**
616     * This is the process holding what we currently consider to be
617     * the "home" activity.
618     */
619    ProcessRecord mHomeProcess;
620
621    /**
622     * This is the process holding the activity the user last visited that
623     * is in a different process from the one they are currently in.
624     */
625    ProcessRecord mPreviousProcess;
626
627    /**
628     * The time at which the previous process was last visible.
629     */
630    long mPreviousProcessVisibleTime;
631
632    /**
633     * Which uses have been started, so are allowed to run code.
634     */
635    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
636
637    /**
638     * LRU list of history of current users.  Most recently current is at the end.
639     */
640    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
641
642    /**
643     * Constant array of the users that are currently started.
644     */
645    int[] mStartedUserArray = new int[] { 0 };
646
647    /**
648     * Registered observers of the user switching mechanics.
649     */
650    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
651            = new RemoteCallbackList<IUserSwitchObserver>();
652
653    /**
654     * Currently active user switch.
655     */
656    Object mCurUserSwitchCallback;
657
658    /**
659     * Packages that the user has asked to have run in screen size
660     * compatibility mode instead of filling the screen.
661     */
662    final CompatModePackages mCompatModePackages;
663
664    /**
665     * Set of IntentSenderRecord objects that are currently active.
666     */
667    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
668            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
669
670    /**
671     * Fingerprints (hashCode()) of stack traces that we've
672     * already logged DropBox entries for.  Guarded by itself.  If
673     * something (rogue user app) forces this over
674     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
675     */
676    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
677    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
678
679    /**
680     * Strict Mode background batched logging state.
681     *
682     * The string buffer is guarded by itself, and its lock is also
683     * used to determine if another batched write is already
684     * in-flight.
685     */
686    private final StringBuilder mStrictModeBuffer = new StringBuilder();
687
688    /**
689     * Keeps track of all IIntentReceivers that have been registered for
690     * broadcasts.  Hash keys are the receiver IBinder, hash value is
691     * a ReceiverList.
692     */
693    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
694            new HashMap<IBinder, ReceiverList>();
695
696    /**
697     * Resolver for broadcast intents to registered receivers.
698     * Holds BroadcastFilter (subclass of IntentFilter).
699     */
700    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
701            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
702        @Override
703        protected boolean allowFilterResult(
704                BroadcastFilter filter, List<BroadcastFilter> dest) {
705            IBinder target = filter.receiverList.receiver.asBinder();
706            for (int i=dest.size()-1; i>=0; i--) {
707                if (dest.get(i).receiverList.receiver.asBinder() == target) {
708                    return false;
709                }
710            }
711            return true;
712        }
713
714        @Override
715        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
716            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
717                    || userId == filter.owningUserId) {
718                return super.newResult(filter, match, userId);
719            }
720            return null;
721        }
722
723        @Override
724        protected BroadcastFilter[] newArray(int size) {
725            return new BroadcastFilter[size];
726        }
727
728        @Override
729        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
730            return packageName.equals(filter.packageName);
731        }
732    };
733
734    /**
735     * State of all active sticky broadcasts per user.  Keys are the action of the
736     * sticky Intent, values are an ArrayList of all broadcasted intents with
737     * that action (which should usually be one).  The SparseArray is keyed
738     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
739     * for stickies that are sent to all users.
740     */
741    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
742            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
743
744    final ActiveServices mServices;
745
746    final static class Association {
747        final int mSourceUid;
748        final String mSourceProcess;
749        final int mTargetUid;
750        final ComponentName mTargetComponent;
751        final String mTargetProcess;
752
753        int mCount;
754        long mTime;
755
756        int mNesting;
757        long mStartTime;
758
759        Association(int sourceUid, String sourceProcess, int targetUid,
760                ComponentName targetComponent, String targetProcess) {
761            mSourceUid = sourceUid;
762            mSourceProcess = sourceProcess;
763            mTargetUid = targetUid;
764            mTargetComponent = targetComponent;
765            mTargetProcess = targetProcess;
766        }
767    }
768
769    /**
770     * When service association tracking is enabled, this is all of the associations we
771     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
772     * -> association data.
773     */
774    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
775            mAssociations = new SparseArray<>();
776    boolean mTrackingAssociations;
777
778    /**
779     * Backup/restore process management
780     */
781    String mBackupAppName = null;
782    BackupRecord mBackupTarget = null;
783
784    final ProviderMap mProviderMap;
785
786    /**
787     * List of content providers who have clients waiting for them.  The
788     * application is currently being launched and the provider will be
789     * removed from this list once it is published.
790     */
791    final ArrayList<ContentProviderRecord> mLaunchingProviders
792            = new ArrayList<ContentProviderRecord>();
793
794    /**
795     * File storing persisted {@link #mGrantedUriPermissions}.
796     */
797    private final AtomicFile mGrantFile;
798
799    /** XML constants used in {@link #mGrantFile} */
800    private static final String TAG_URI_GRANTS = "uri-grants";
801    private static final String TAG_URI_GRANT = "uri-grant";
802    private static final String ATTR_USER_HANDLE = "userHandle";
803    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
804    private static final String ATTR_TARGET_USER_ID = "targetUserId";
805    private static final String ATTR_SOURCE_PKG = "sourcePkg";
806    private static final String ATTR_TARGET_PKG = "targetPkg";
807    private static final String ATTR_URI = "uri";
808    private static final String ATTR_MODE_FLAGS = "modeFlags";
809    private static final String ATTR_CREATED_TIME = "createdTime";
810    private static final String ATTR_PREFIX = "prefix";
811
812    /**
813     * Global set of specific {@link Uri} permissions that have been granted.
814     * This optimized lookup structure maps from {@link UriPermission#targetUid}
815     * to {@link UriPermission#uri} to {@link UriPermission}.
816     */
817    @GuardedBy("this")
818    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
819            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
820
821    public static class GrantUri {
822        public final int sourceUserId;
823        public final Uri uri;
824        public boolean prefix;
825
826        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
827            this.sourceUserId = sourceUserId;
828            this.uri = uri;
829            this.prefix = prefix;
830        }
831
832        @Override
833        public int hashCode() {
834            int hashCode = 1;
835            hashCode = 31 * hashCode + sourceUserId;
836            hashCode = 31 * hashCode + uri.hashCode();
837            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
838            return hashCode;
839        }
840
841        @Override
842        public boolean equals(Object o) {
843            if (o instanceof GrantUri) {
844                GrantUri other = (GrantUri) o;
845                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
846                        && prefix == other.prefix;
847            }
848            return false;
849        }
850
851        @Override
852        public String toString() {
853            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
854            if (prefix) result += " [prefix]";
855            return result;
856        }
857
858        public String toSafeString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
865            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
866                    ContentProvider.getUriWithoutUserId(uri), false);
867        }
868    }
869
870    CoreSettingsObserver mCoreSettingsObserver;
871
872    /**
873     * Thread-local storage used to carry caller permissions over through
874     * indirect content-provider access.
875     */
876    private class Identity {
877        public final IBinder token;
878        public final int pid;
879        public final int uid;
880
881        Identity(IBinder _token, int _pid, int _uid) {
882            token = _token;
883            pid = _pid;
884            uid = _uid;
885        }
886    }
887
888    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
889
890    /**
891     * All information we have collected about the runtime performance of
892     * any user id that can impact battery performance.
893     */
894    final BatteryStatsService mBatteryStatsService;
895
896    /**
897     * Information about component usage
898     */
899    UsageStatsManagerInternal mUsageStatsService;
900
901    /**
902     * Information about and control over application operations
903     */
904    final AppOpsService mAppOpsService;
905
906    /**
907     * Save recent tasks information across reboots.
908     */
909    final TaskPersister mTaskPersister;
910
911    /**
912     * Current configuration information.  HistoryRecord objects are given
913     * a reference to this object to indicate which configuration they are
914     * currently running in, so this object must be kept immutable.
915     */
916    Configuration mConfiguration = new Configuration();
917
918    /**
919     * Current sequencing integer of the configuration, for skipping old
920     * configurations.
921     */
922    int mConfigurationSeq = 0;
923
924    /**
925     * Hardware-reported OpenGLES version.
926     */
927    final int GL_ES_VERSION;
928
929    /**
930     * List of initialization arguments to pass to all processes when binding applications to them.
931     * For example, references to the commonly used services.
932     */
933    HashMap<String, IBinder> mAppBindArgs;
934
935    /**
936     * Temporary to avoid allocations.  Protected by main lock.
937     */
938    final StringBuilder mStringBuilder = new StringBuilder(256);
939
940    /**
941     * Used to control how we initialize the service.
942     */
943    ComponentName mTopComponent;
944    String mTopAction = Intent.ACTION_MAIN;
945    String mTopData;
946    boolean mProcessesReady = false;
947    boolean mSystemReady = false;
948    boolean mBooting = false;
949    boolean mCallFinishBooting = false;
950    boolean mBootAnimationComplete = false;
951    boolean mWaitingUpdate = false;
952    boolean mDidUpdate = false;
953    boolean mOnBattery = false;
954    boolean mLaunchWarningShown = false;
955
956    Context mContext;
957
958    int mFactoryTest;
959
960    boolean mCheckedForSetup;
961
962    /**
963     * The time at which we will allow normal application switches again,
964     * after a call to {@link #stopAppSwitches()}.
965     */
966    long mAppSwitchesAllowedTime;
967
968    /**
969     * This is set to true after the first switch after mAppSwitchesAllowedTime
970     * is set; any switches after that will clear the time.
971     */
972    boolean mDidAppSwitch;
973
974    /**
975     * Last time (in realtime) at which we checked for power usage.
976     */
977    long mLastPowerCheckRealtime;
978
979    /**
980     * Last time (in uptime) at which we checked for power usage.
981     */
982    long mLastPowerCheckUptime;
983
984    /**
985     * Set while we are wanting to sleep, to prevent any
986     * activities from being started/resumed.
987     */
988    private boolean mSleeping = false;
989
990    /**
991     * Set while we are running a voice interaction.  This overrides
992     * sleeping while it is active.
993     */
994    private boolean mRunningVoice = false;
995
996    /**
997     * State of external calls telling us if the device is awake or asleep.
998     */
999    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1000
1001    static final int LOCK_SCREEN_HIDDEN = 0;
1002    static final int LOCK_SCREEN_LEAVING = 1;
1003    static final int LOCK_SCREEN_SHOWN = 2;
1004    /**
1005     * State of external call telling us if the lock screen is shown.
1006     */
1007    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1008
1009    /**
1010     * Set if we are shutting down the system, similar to sleeping.
1011     */
1012    boolean mShuttingDown = false;
1013
1014    /**
1015     * Current sequence id for oom_adj computation traversal.
1016     */
1017    int mAdjSeq = 0;
1018
1019    /**
1020     * Current sequence id for process LRU updating.
1021     */
1022    int mLruSeq = 0;
1023
1024    /**
1025     * Keep track of the non-cached/empty process we last found, to help
1026     * determine how to distribute cached/empty processes next time.
1027     */
1028    int mNumNonCachedProcs = 0;
1029
1030    /**
1031     * Keep track of the number of cached hidden procs, to balance oom adj
1032     * distribution between those and empty procs.
1033     */
1034    int mNumCachedHiddenProcs = 0;
1035
1036    /**
1037     * Keep track of the number of service processes we last found, to
1038     * determine on the next iteration which should be B services.
1039     */
1040    int mNumServiceProcs = 0;
1041    int mNewNumAServiceProcs = 0;
1042    int mNewNumServiceProcs = 0;
1043
1044    /**
1045     * Allow the current computed overall memory level of the system to go down?
1046     * This is set to false when we are killing processes for reasons other than
1047     * memory management, so that the now smaller process list will not be taken as
1048     * an indication that memory is tighter.
1049     */
1050    boolean mAllowLowerMemLevel = false;
1051
1052    /**
1053     * The last computed memory level, for holding when we are in a state that
1054     * processes are going away for other reasons.
1055     */
1056    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1057
1058    /**
1059     * The last total number of process we have, to determine if changes actually look
1060     * like a shrinking number of process due to lower RAM.
1061     */
1062    int mLastNumProcesses;
1063
1064    /**
1065     * The uptime of the last time we performed idle maintenance.
1066     */
1067    long mLastIdleTime = SystemClock.uptimeMillis();
1068
1069    /**
1070     * Total time spent with RAM that has been added in the past since the last idle time.
1071     */
1072    long mLowRamTimeSinceLastIdle = 0;
1073
1074    /**
1075     * If RAM is currently low, when that horrible situation started.
1076     */
1077    long mLowRamStartTime = 0;
1078
1079    /**
1080     * For reporting to battery stats the current top application.
1081     */
1082    private String mCurResumedPackage = null;
1083    private int mCurResumedUid = -1;
1084
1085    /**
1086     * For reporting to battery stats the apps currently running foreground
1087     * service.  The ProcessMap is package/uid tuples; each of these contain
1088     * an array of the currently foreground processes.
1089     */
1090    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1091            = new ProcessMap<ArrayList<ProcessRecord>>();
1092
1093    /**
1094     * This is set if we had to do a delayed dexopt of an app before launching
1095     * it, to increase the ANR timeouts in that case.
1096     */
1097    boolean mDidDexOpt;
1098
1099    /**
1100     * Set if the systemServer made a call to enterSafeMode.
1101     */
1102    boolean mSafeMode;
1103
1104    /**
1105     * If true, we are running under a test environment so will sample PSS from processes
1106     * much more rapidly to try to collect better data when the tests are rapidly
1107     * running through apps.
1108     */
1109    boolean mTestPssMode = false;
1110
1111    String mDebugApp = null;
1112    boolean mWaitForDebugger = false;
1113    boolean mDebugTransient = false;
1114    String mOrigDebugApp = null;
1115    boolean mOrigWaitForDebugger = false;
1116    boolean mAlwaysFinishActivities = false;
1117    IActivityController mController = null;
1118    String mProfileApp = null;
1119    ProcessRecord mProfileProc = null;
1120    String mProfileFile;
1121    ParcelFileDescriptor mProfileFd;
1122    int mSamplingInterval = 0;
1123    boolean mAutoStopProfiler = false;
1124    int mProfileType = 0;
1125    String mOpenGlTraceApp = null;
1126    final ArrayMap<String, Long> mMemWatchProcesses = new ArrayMap<>();
1127    String mMemWatchDumpProcName;
1128    String mMemWatchDumpFile;
1129    int mMemWatchDumpPid;
1130    int mMemWatchDumpUid;
1131
1132    final long[] mTmpLong = new long[1];
1133
1134    static class ProcessChangeItem {
1135        static final int CHANGE_ACTIVITIES = 1<<0;
1136        static final int CHANGE_PROCESS_STATE = 1<<1;
1137        int changes;
1138        int uid;
1139        int pid;
1140        int processState;
1141        boolean foregroundActivities;
1142    }
1143
1144    final RemoteCallbackList<IProcessObserver> mProcessObservers
1145            = new RemoteCallbackList<IProcessObserver>();
1146    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1147
1148    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1149            = new ArrayList<ProcessChangeItem>();
1150    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1151            = new ArrayList<ProcessChangeItem>();
1152
1153    /**
1154     * Runtime CPU use collection thread.  This object's lock is used to
1155     * perform synchronization with the thread (notifying it to run).
1156     */
1157    final Thread mProcessCpuThread;
1158
1159    /**
1160     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1161     * Must acquire this object's lock when accessing it.
1162     * NOTE: this lock will be held while doing long operations (trawling
1163     * through all processes in /proc), so it should never be acquired by
1164     * any critical paths such as when holding the main activity manager lock.
1165     */
1166    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1167            MONITOR_THREAD_CPU_USAGE);
1168    final AtomicLong mLastCpuTime = new AtomicLong(0);
1169    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1170
1171    long mLastWriteTime = 0;
1172
1173    /**
1174     * Used to retain an update lock when the foreground activity is in
1175     * immersive mode.
1176     */
1177    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1178
1179    /**
1180     * Set to true after the system has finished booting.
1181     */
1182    boolean mBooted = false;
1183
1184    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1185    int mProcessLimitOverride = -1;
1186
1187    WindowManagerService mWindowManager;
1188
1189    final ActivityThread mSystemThread;
1190
1191    // Holds the current foreground user's id
1192    int mCurrentUserId = 0;
1193    // Holds the target user's id during a user switch
1194    int mTargetUserId = UserHandle.USER_NULL;
1195    // If there are multiple profiles for the current user, their ids are here
1196    // Currently only the primary user can have managed profiles
1197    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1198
1199    /**
1200     * Mapping from each known user ID to the profile group ID it is associated with.
1201     */
1202    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1203
1204    private UserManagerService mUserManager;
1205
1206    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1207        final ProcessRecord mApp;
1208        final int mPid;
1209        final IApplicationThread mAppThread;
1210
1211        AppDeathRecipient(ProcessRecord app, int pid,
1212                IApplicationThread thread) {
1213            if (DEBUG_ALL) Slog.v(
1214                TAG, "New death recipient " + this
1215                + " for thread " + thread.asBinder());
1216            mApp = app;
1217            mPid = pid;
1218            mAppThread = thread;
1219        }
1220
1221        @Override
1222        public void binderDied() {
1223            if (DEBUG_ALL) Slog.v(
1224                TAG, "Death received in " + this
1225                + " for thread " + mAppThread.asBinder());
1226            synchronized(ActivityManagerService.this) {
1227                appDiedLocked(mApp, mPid, mAppThread);
1228            }
1229        }
1230    }
1231
1232    static final int SHOW_ERROR_MSG = 1;
1233    static final int SHOW_NOT_RESPONDING_MSG = 2;
1234    static final int SHOW_FACTORY_ERROR_MSG = 3;
1235    static final int UPDATE_CONFIGURATION_MSG = 4;
1236    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1237    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1238    static final int SERVICE_TIMEOUT_MSG = 12;
1239    static final int UPDATE_TIME_ZONE = 13;
1240    static final int SHOW_UID_ERROR_MSG = 14;
1241    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1242    static final int PROC_START_TIMEOUT_MSG = 20;
1243    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1244    static final int KILL_APPLICATION_MSG = 22;
1245    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1246    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1247    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1248    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1249    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1250    static final int CLEAR_DNS_CACHE_MSG = 28;
1251    static final int UPDATE_HTTP_PROXY_MSG = 29;
1252    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1253    static final int DISPATCH_PROCESSES_CHANGED = 31;
1254    static final int DISPATCH_PROCESS_DIED = 32;
1255    static final int REPORT_MEM_USAGE_MSG = 33;
1256    static final int REPORT_USER_SWITCH_MSG = 34;
1257    static final int CONTINUE_USER_SWITCH_MSG = 35;
1258    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1259    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1260    static final int PERSIST_URI_GRANTS_MSG = 38;
1261    static final int REQUEST_ALL_PSS_MSG = 39;
1262    static final int START_PROFILES_MSG = 40;
1263    static final int UPDATE_TIME = 41;
1264    static final int SYSTEM_USER_START_MSG = 42;
1265    static final int SYSTEM_USER_CURRENT_MSG = 43;
1266    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1267    static final int FINISH_BOOTING_MSG = 45;
1268    static final int START_USER_SWITCH_MSG = 46;
1269    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1270    static final int DISMISS_DIALOG_MSG = 48;
1271    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1272    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1273    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1274    static final int DELETE_DUMPHEAP_MSG = 52;
1275
1276    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1277    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1278    static final int FIRST_COMPAT_MODE_MSG = 300;
1279    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1280
1281    CompatModeDialog mCompatModeDialog;
1282    long mLastMemUsageReportTime = 0;
1283
1284    /**
1285     * Flag whether the current user is a "monkey", i.e. whether
1286     * the UI is driven by a UI automation tool.
1287     */
1288    private boolean mUserIsMonkey;
1289
1290    /** Flag whether the device has a Recents UI */
1291    boolean mHasRecents;
1292
1293    /** The dimensions of the thumbnails in the Recents UI. */
1294    int mThumbnailWidth;
1295    int mThumbnailHeight;
1296
1297    final ServiceThread mHandlerThread;
1298    final MainHandler mHandler;
1299
1300    final class MainHandler extends Handler {
1301        public MainHandler(Looper looper) {
1302            super(looper, null, true);
1303        }
1304
1305        @Override
1306        public void handleMessage(Message msg) {
1307            switch (msg.what) {
1308            case SHOW_ERROR_MSG: {
1309                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1310                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1311                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord proc = (ProcessRecord)data.get("app");
1314                    AppErrorResult res = (AppErrorResult) data.get("result");
1315                    if (proc != null && proc.crashDialog != null) {
1316                        Slog.e(TAG, "App already has crash dialog: " + proc);
1317                        if (res != null) {
1318                            res.set(0);
1319                        }
1320                        return;
1321                    }
1322                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1323                            >= Process.FIRST_APPLICATION_UID
1324                            && proc.pid != MY_PID);
1325                    for (int userId : mCurrentProfileIds) {
1326                        isBackground &= (proc.userId != userId);
1327                    }
1328                    if (isBackground && !showBackground) {
1329                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1330                        if (res != null) {
1331                            res.set(0);
1332                        }
1333                        return;
1334                    }
1335                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1336                        Dialog d = new AppErrorDialog(mContext,
1337                                ActivityManagerService.this, res, proc);
1338                        d.show();
1339                        proc.crashDialog = d;
1340                    } else {
1341                        // The device is asleep, so just pretend that the user
1342                        // saw a crash dialog and hit "force quit".
1343                        if (res != null) {
1344                            res.set(0);
1345                        }
1346                    }
1347                }
1348
1349                ensureBootCompleted();
1350            } break;
1351            case SHOW_NOT_RESPONDING_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1354                    ProcessRecord proc = (ProcessRecord)data.get("app");
1355                    if (proc != null && proc.anrDialog != null) {
1356                        Slog.e(TAG, "App already has anr dialog: " + proc);
1357                        return;
1358                    }
1359
1360                    Intent intent = new Intent("android.intent.action.ANR");
1361                    if (!mProcessesReady) {
1362                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1363                                | Intent.FLAG_RECEIVER_FOREGROUND);
1364                    }
1365                    broadcastIntentLocked(null, null, intent,
1366                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1367                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1368
1369                    if (mShowDialogs) {
1370                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1371                                mContext, proc, (ActivityRecord)data.get("activity"),
1372                                msg.arg1 != 0);
1373                        d.show();
1374                        proc.anrDialog = d;
1375                    } else {
1376                        // Just kill the app if there is no dialog to be shown.
1377                        killAppAtUsersRequest(proc, null);
1378                    }
1379                }
1380
1381                ensureBootCompleted();
1382            } break;
1383            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1384                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1385                synchronized (ActivityManagerService.this) {
1386                    ProcessRecord proc = (ProcessRecord) data.get("app");
1387                    if (proc == null) {
1388                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1389                        break;
1390                    }
1391                    if (proc.crashDialog != null) {
1392                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1393                        return;
1394                    }
1395                    AppErrorResult res = (AppErrorResult) data.get("result");
1396                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1397                        Dialog d = new StrictModeViolationDialog(mContext,
1398                                ActivityManagerService.this, res, proc);
1399                        d.show();
1400                        proc.crashDialog = d;
1401                    } else {
1402                        // The device is asleep, so just pretend that the user
1403                        // saw a crash dialog and hit "force quit".
1404                        res.set(0);
1405                    }
1406                }
1407                ensureBootCompleted();
1408            } break;
1409            case SHOW_FACTORY_ERROR_MSG: {
1410                Dialog d = new FactoryErrorDialog(
1411                    mContext, msg.getData().getCharSequence("msg"));
1412                d.show();
1413                ensureBootCompleted();
1414            } break;
1415            case UPDATE_CONFIGURATION_MSG: {
1416                final ContentResolver resolver = mContext.getContentResolver();
1417                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1418            } break;
1419            case GC_BACKGROUND_PROCESSES_MSG: {
1420                synchronized (ActivityManagerService.this) {
1421                    performAppGcsIfAppropriateLocked();
1422                }
1423            } break;
1424            case WAIT_FOR_DEBUGGER_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ProcessRecord app = (ProcessRecord)msg.obj;
1427                    if (msg.arg1 != 0) {
1428                        if (!app.waitedForDebugger) {
1429                            Dialog d = new AppWaitingForDebuggerDialog(
1430                                    ActivityManagerService.this,
1431                                    mContext, app);
1432                            app.waitDialog = d;
1433                            app.waitedForDebugger = true;
1434                            d.show();
1435                        }
1436                    } else {
1437                        if (app.waitDialog != null) {
1438                            app.waitDialog.dismiss();
1439                            app.waitDialog = null;
1440                        }
1441                    }
1442                }
1443            } break;
1444            case SERVICE_TIMEOUT_MSG: {
1445                if (mDidDexOpt) {
1446                    mDidDexOpt = false;
1447                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1448                    nmsg.obj = msg.obj;
1449                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1450                    return;
1451                }
1452                mServices.serviceTimeout((ProcessRecord)msg.obj);
1453            } break;
1454            case UPDATE_TIME_ZONE: {
1455                synchronized (ActivityManagerService.this) {
1456                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1457                        ProcessRecord r = mLruProcesses.get(i);
1458                        if (r.thread != null) {
1459                            try {
1460                                r.thread.updateTimeZone();
1461                            } catch (RemoteException ex) {
1462                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1463                            }
1464                        }
1465                    }
1466                }
1467            } break;
1468            case CLEAR_DNS_CACHE_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1471                        ProcessRecord r = mLruProcesses.get(i);
1472                        if (r.thread != null) {
1473                            try {
1474                                r.thread.clearDnsCache();
1475                            } catch (RemoteException ex) {
1476                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1477                            }
1478                        }
1479                    }
1480                }
1481            } break;
1482            case UPDATE_HTTP_PROXY_MSG: {
1483                ProxyInfo proxy = (ProxyInfo)msg.obj;
1484                String host = "";
1485                String port = "";
1486                String exclList = "";
1487                Uri pacFileUrl = Uri.EMPTY;
1488                if (proxy != null) {
1489                    host = proxy.getHost();
1490                    port = Integer.toString(proxy.getPort());
1491                    exclList = proxy.getExclusionListAsString();
1492                    pacFileUrl = proxy.getPacFileUrl();
1493                }
1494                synchronized (ActivityManagerService.this) {
1495                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1496                        ProcessRecord r = mLruProcesses.get(i);
1497                        if (r.thread != null) {
1498                            try {
1499                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1500                            } catch (RemoteException ex) {
1501                                Slog.w(TAG, "Failed to update http proxy for: " +
1502                                        r.info.processName);
1503                            }
1504                        }
1505                    }
1506                }
1507            } break;
1508            case SHOW_UID_ERROR_MSG: {
1509                if (mShowDialogs) {
1510                    AlertDialog d = new BaseErrorDialog(mContext);
1511                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1512                    d.setCancelable(false);
1513                    d.setTitle(mContext.getText(R.string.android_system_label));
1514                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1515                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1516                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1517                    d.show();
1518                }
1519            } break;
1520            case SHOW_FINGERPRINT_ERROR_MSG: {
1521                if (mShowDialogs) {
1522                    AlertDialog d = new BaseErrorDialog(mContext);
1523                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524                    d.setCancelable(false);
1525                    d.setTitle(mContext.getText(R.string.android_system_label));
1526                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1527                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1529                    d.show();
1530                }
1531            } break;
1532            case PROC_START_TIMEOUT_MSG: {
1533                if (mDidDexOpt) {
1534                    mDidDexOpt = false;
1535                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1536                    nmsg.obj = msg.obj;
1537                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1538                    return;
1539                }
1540                ProcessRecord app = (ProcessRecord)msg.obj;
1541                synchronized (ActivityManagerService.this) {
1542                    processStartTimedOutLocked(app);
1543                }
1544            } break;
1545            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1548                }
1549            } break;
1550            case KILL_APPLICATION_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    int appid = msg.arg1;
1553                    boolean restart = (msg.arg2 == 1);
1554                    Bundle bundle = (Bundle)msg.obj;
1555                    String pkg = bundle.getString("pkg");
1556                    String reason = bundle.getString("reason");
1557                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1558                            false, UserHandle.USER_ALL, reason);
1559                }
1560            } break;
1561            case FINALIZE_PENDING_INTENT_MSG: {
1562                ((PendingIntentRecord)msg.obj).completeFinalize();
1563            } break;
1564            case POST_HEAVY_NOTIFICATION_MSG: {
1565                INotificationManager inm = NotificationManager.getService();
1566                if (inm == null) {
1567                    return;
1568                }
1569
1570                ActivityRecord root = (ActivityRecord)msg.obj;
1571                ProcessRecord process = root.app;
1572                if (process == null) {
1573                    return;
1574                }
1575
1576                try {
1577                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1578                    String text = mContext.getString(R.string.heavy_weight_notification,
1579                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1580                    Notification notification = new Notification();
1581                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1582                    notification.when = 0;
1583                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1584                    notification.tickerText = text;
1585                    notification.defaults = 0; // please be quiet
1586                    notification.sound = null;
1587                    notification.vibrate = null;
1588                    notification.color = mContext.getResources().getColor(
1589                            com.android.internal.R.color.system_notification_accent_color);
1590                    notification.setLatestEventInfo(context, text,
1591                            mContext.getText(R.string.heavy_weight_notification_detail),
1592                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1593                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1594                                    new UserHandle(root.userId)));
1595
1596                    try {
1597                        int[] outId = new int[1];
1598                        inm.enqueueNotificationWithTag("android", "android", null,
1599                                R.string.heavy_weight_notification,
1600                                notification, outId, root.userId);
1601                    } catch (RuntimeException e) {
1602                        Slog.w(ActivityManagerService.TAG,
1603                                "Error showing notification for heavy-weight app", e);
1604                    } catch (RemoteException e) {
1605                    }
1606                } catch (NameNotFoundException e) {
1607                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1608                }
1609            } break;
1610            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1611                INotificationManager inm = NotificationManager.getService();
1612                if (inm == null) {
1613                    return;
1614                }
1615                try {
1616                    inm.cancelNotificationWithTag("android", null,
1617                            R.string.heavy_weight_notification,  msg.arg1);
1618                } catch (RuntimeException e) {
1619                    Slog.w(ActivityManagerService.TAG,
1620                            "Error canceling notification for service", e);
1621                } catch (RemoteException e) {
1622                }
1623            } break;
1624            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    checkExcessivePowerUsageLocked(true);
1627                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1628                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1629                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1630                }
1631            } break;
1632            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1633                synchronized (ActivityManagerService.this) {
1634                    ActivityRecord ar = (ActivityRecord)msg.obj;
1635                    if (mCompatModeDialog != null) {
1636                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1637                                ar.info.applicationInfo.packageName)) {
1638                            return;
1639                        }
1640                        mCompatModeDialog.dismiss();
1641                        mCompatModeDialog = null;
1642                    }
1643                    if (ar != null && false) {
1644                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1645                                ar.packageName)) {
1646                            int mode = mCompatModePackages.computeCompatModeLocked(
1647                                    ar.info.applicationInfo);
1648                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1649                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1650                                mCompatModeDialog = new CompatModeDialog(
1651                                        ActivityManagerService.this, mContext,
1652                                        ar.info.applicationInfo);
1653                                mCompatModeDialog.show();
1654                            }
1655                        }
1656                    }
1657                }
1658                break;
1659            }
1660            case DISPATCH_PROCESSES_CHANGED: {
1661                dispatchProcessesChanged();
1662                break;
1663            }
1664            case DISPATCH_PROCESS_DIED: {
1665                final int pid = msg.arg1;
1666                final int uid = msg.arg2;
1667                dispatchProcessDied(pid, uid);
1668                break;
1669            }
1670            case REPORT_MEM_USAGE_MSG: {
1671                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1672                Thread thread = new Thread() {
1673                    @Override public void run() {
1674                        reportMemUsage(memInfos);
1675                    }
1676                };
1677                thread.start();
1678                break;
1679            }
1680            case START_USER_SWITCH_MSG: {
1681                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1682                break;
1683            }
1684            case REPORT_USER_SWITCH_MSG: {
1685                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1686                break;
1687            }
1688            case CONTINUE_USER_SWITCH_MSG: {
1689                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1690                break;
1691            }
1692            case USER_SWITCH_TIMEOUT_MSG: {
1693                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1694                break;
1695            }
1696            case IMMERSIVE_MODE_LOCK_MSG: {
1697                final boolean nextState = (msg.arg1 != 0);
1698                if (mUpdateLock.isHeld() != nextState) {
1699                    if (DEBUG_IMMERSIVE) {
1700                        final ActivityRecord r = (ActivityRecord) msg.obj;
1701                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1702                    }
1703                    if (nextState) {
1704                        mUpdateLock.acquire();
1705                    } else {
1706                        mUpdateLock.release();
1707                    }
1708                }
1709                break;
1710            }
1711            case PERSIST_URI_GRANTS_MSG: {
1712                writeGrantedUriPermissions();
1713                break;
1714            }
1715            case REQUEST_ALL_PSS_MSG: {
1716                synchronized (ActivityManagerService.this) {
1717                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1718                }
1719                break;
1720            }
1721            case START_PROFILES_MSG: {
1722                synchronized (ActivityManagerService.this) {
1723                    startProfilesLocked();
1724                }
1725                break;
1726            }
1727            case UPDATE_TIME: {
1728                synchronized (ActivityManagerService.this) {
1729                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1730                        ProcessRecord r = mLruProcesses.get(i);
1731                        if (r.thread != null) {
1732                            try {
1733                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1734                            } catch (RemoteException ex) {
1735                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1736                            }
1737                        }
1738                    }
1739                }
1740                break;
1741            }
1742            case SYSTEM_USER_START_MSG: {
1743                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1744                        Integer.toString(msg.arg1), msg.arg1);
1745                mSystemServiceManager.startUser(msg.arg1);
1746                break;
1747            }
1748            case SYSTEM_USER_CURRENT_MSG: {
1749                mBatteryStatsService.noteEvent(
1750                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1751                        Integer.toString(msg.arg2), msg.arg2);
1752                mBatteryStatsService.noteEvent(
1753                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1754                        Integer.toString(msg.arg1), msg.arg1);
1755                mSystemServiceManager.switchUser(msg.arg1);
1756                break;
1757            }
1758            case ENTER_ANIMATION_COMPLETE_MSG: {
1759                synchronized (ActivityManagerService.this) {
1760                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1761                    if (r != null && r.app != null && r.app.thread != null) {
1762                        try {
1763                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1764                        } catch (RemoteException e) {
1765                        }
1766                    }
1767                }
1768                break;
1769            }
1770            case FINISH_BOOTING_MSG: {
1771                if (msg.arg1 != 0) {
1772                    finishBooting();
1773                }
1774                if (msg.arg2 != 0) {
1775                    enableScreenAfterBoot();
1776                }
1777                break;
1778            }
1779            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1780                try {
1781                    Locale l = (Locale) msg.obj;
1782                    IBinder service = ServiceManager.getService("mount");
1783                    IMountService mountService = IMountService.Stub.asInterface(service);
1784                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1785                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1786                } catch (RemoteException e) {
1787                    Log.e(TAG, "Error storing locale for decryption UI", e);
1788                }
1789                break;
1790            }
1791            case DISMISS_DIALOG_MSG: {
1792                final Dialog d = (Dialog) msg.obj;
1793                d.dismiss();
1794                break;
1795            }
1796            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1797                synchronized (ActivityManagerService.this) {
1798                    int i = mTaskStackListeners.beginBroadcast();
1799                    while (i > 0) {
1800                        i--;
1801                        try {
1802                            // Make a one-way callback to the listener
1803                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1804                        } catch (RemoteException e){
1805                            // Handled by the RemoteCallbackList
1806                        }
1807                    }
1808                    mTaskStackListeners.finishBroadcast();
1809                }
1810                break;
1811            }
1812            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1813                final int uid = msg.arg1;
1814                final byte[] firstPacket = (byte[]) msg.obj;
1815
1816                synchronized (mPidsSelfLocked) {
1817                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1818                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1819                        if (p.uid == uid) {
1820                            try {
1821                                p.thread.notifyCleartextNetwork(firstPacket);
1822                            } catch (RemoteException ignored) {
1823                            }
1824                        }
1825                    }
1826                }
1827                break;
1828            }
1829            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1830                final String procName;
1831                final int uid;
1832                final long memLimit;
1833                synchronized (ActivityManagerService.this) {
1834                    procName = mMemWatchDumpProcName;
1835                    uid = mMemWatchDumpUid;
1836                    Long limit = mMemWatchProcesses.get(procName);
1837                    memLimit = limit != null ? limit : 0;
1838                }
1839                if (procName == null) {
1840                    return;
1841                }
1842
1843                if (DEBUG_PSS) Slog.d(TAG, "Showing dump heap notification from "
1844                        + procName + "/" + uid);
1845
1846                INotificationManager inm = NotificationManager.getService();
1847                if (inm == null) {
1848                    return;
1849                }
1850
1851                String text = mContext.getString(R.string.dump_heap_notification, procName);
1852                Notification notification = new Notification();
1853                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1854                notification.when = 0;
1855                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1856                notification.tickerText = text;
1857                notification.defaults = 0; // please be quiet
1858                notification.sound = null;
1859                notification.vibrate = null;
1860                notification.color = mContext.getResources().getColor(
1861                        com.android.internal.R.color.system_notification_accent_color);
1862                Intent deleteIntent = new Intent();
1863                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1864                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1865                        deleteIntent, 0, UserHandle.OWNER);
1866                Intent intent = new Intent();
1867                intent.setClassName("android", DumpHeapActivity.class.getName());
1868                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1869                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1870                int userId = UserHandle.getUserId(uid);
1871                notification.setLatestEventInfo(mContext, text,
1872                        mContext.getText(R.string.dump_heap_notification_detail),
1873                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1874                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1875                                new UserHandle(userId)));
1876
1877                try {
1878                    int[] outId = new int[1];
1879                    inm.enqueueNotificationWithTag("android", "android", null,
1880                            R.string.dump_heap_notification,
1881                            notification, outId, userId);
1882                } catch (RuntimeException e) {
1883                    Slog.w(ActivityManagerService.TAG,
1884                            "Error showing notification for dump heap", e);
1885                } catch (RemoteException e) {
1886                }
1887            } break;
1888            case DELETE_DUMPHEAP_MSG: {
1889                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1890                        DumpHeapActivity.JAVA_URI,
1891                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1892                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1893                        UserHandle.myUserId());
1894                synchronized (ActivityManagerService.this) {
1895                    mMemWatchDumpFile = null;
1896                    mMemWatchDumpProcName = null;
1897                    mMemWatchDumpPid = -1;
1898                    mMemWatchDumpUid = -1;
1899                }
1900            } break;
1901            }
1902        }
1903    };
1904
1905    static final int COLLECT_PSS_BG_MSG = 1;
1906
1907    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1908        @Override
1909        public void handleMessage(Message msg) {
1910            switch (msg.what) {
1911            case COLLECT_PSS_BG_MSG: {
1912                long start = SystemClock.uptimeMillis();
1913                MemInfoReader memInfo = null;
1914                synchronized (ActivityManagerService.this) {
1915                    if (mFullPssPending) {
1916                        mFullPssPending = false;
1917                        memInfo = new MemInfoReader();
1918                    }
1919                }
1920                if (memInfo != null) {
1921                    updateCpuStatsNow();
1922                    long nativeTotalPss = 0;
1923                    synchronized (mProcessCpuTracker) {
1924                        final int N = mProcessCpuTracker.countStats();
1925                        for (int j=0; j<N; j++) {
1926                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1927                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1928                                // This is definitely an application process; skip it.
1929                                continue;
1930                            }
1931                            synchronized (mPidsSelfLocked) {
1932                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1933                                    // This is one of our own processes; skip it.
1934                                    continue;
1935                                }
1936                            }
1937                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1938                        }
1939                    }
1940                    memInfo.readMemInfo();
1941                    synchronized (ActivityManagerService.this) {
1942                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1943                                + (SystemClock.uptimeMillis()-start) + "ms");
1944                        final long cachedKb = memInfo.getCachedSizeKb();
1945                        final long freeKb = memInfo.getFreeSizeKb();
1946                        final long zramKb = memInfo.getZramTotalSizeKb();
1947                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1948                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1949                                kernelKb*1024, nativeTotalPss*1024);
1950                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1951                                nativeTotalPss);
1952                    }
1953                }
1954
1955                int num = 0;
1956                long[] tmp = new long[1];
1957                do {
1958                    ProcessRecord proc;
1959                    int procState;
1960                    int pid;
1961                    long lastPssTime;
1962                    synchronized (ActivityManagerService.this) {
1963                        if (mPendingPssProcesses.size() <= 0) {
1964                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1965                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1966                            mPendingPssProcesses.clear();
1967                            return;
1968                        }
1969                        proc = mPendingPssProcesses.remove(0);
1970                        procState = proc.pssProcState;
1971                        lastPssTime = proc.lastPssTime;
1972                        if (proc.thread != null && procState == proc.setProcState
1973                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1974                                        < SystemClock.uptimeMillis()) {
1975                            pid = proc.pid;
1976                        } else {
1977                            proc = null;
1978                            pid = 0;
1979                        }
1980                    }
1981                    if (proc != null) {
1982                        long pss = Debug.getPss(pid, tmp, null);
1983                        synchronized (ActivityManagerService.this) {
1984                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1985                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1986                                num++;
1987                                recordPssSampleLocked(proc, procState, pss, tmp[0],
1988                                        SystemClock.uptimeMillis());
1989                            }
1990                        }
1991                    }
1992                } while (true);
1993            }
1994            }
1995        }
1996    };
1997
1998    public void setSystemProcess() {
1999        try {
2000            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2001            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2002            ServiceManager.addService("meminfo", new MemBinder(this));
2003            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2004            ServiceManager.addService("dbinfo", new DbBinder(this));
2005            if (MONITOR_CPU_USAGE) {
2006                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2007            }
2008            ServiceManager.addService("permission", new PermissionController(this));
2009            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2010
2011            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2012                    "android", STOCK_PM_FLAGS);
2013            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2014
2015            synchronized (this) {
2016                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2017                app.persistent = true;
2018                app.pid = MY_PID;
2019                app.maxAdj = ProcessList.SYSTEM_ADJ;
2020                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2021                mProcessNames.put(app.processName, app.uid, app);
2022                synchronized (mPidsSelfLocked) {
2023                    mPidsSelfLocked.put(app.pid, app);
2024                }
2025                updateLruProcessLocked(app, false, null);
2026                updateOomAdjLocked();
2027            }
2028        } catch (PackageManager.NameNotFoundException e) {
2029            throw new RuntimeException(
2030                    "Unable to find android system package", e);
2031        }
2032    }
2033
2034    public void setWindowManager(WindowManagerService wm) {
2035        mWindowManager = wm;
2036        mStackSupervisor.setWindowManager(wm);
2037    }
2038
2039    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2040        mUsageStatsService = usageStatsManager;
2041    }
2042
2043    public void startObservingNativeCrashes() {
2044        final NativeCrashListener ncl = new NativeCrashListener(this);
2045        ncl.start();
2046    }
2047
2048    public IAppOpsService getAppOpsService() {
2049        return mAppOpsService;
2050    }
2051
2052    static class MemBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        MemBinder(ActivityManagerService activityManagerService) {
2055            mActivityManagerService = activityManagerService;
2056        }
2057
2058        @Override
2059        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2060            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2061                    != PackageManager.PERMISSION_GRANTED) {
2062                pw.println("Permission Denial: can't dump meminfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2069        }
2070    }
2071
2072    static class GraphicsBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        GraphicsBinder(ActivityManagerService activityManagerService) {
2075            mActivityManagerService = activityManagerService;
2076        }
2077
2078        @Override
2079        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2081                    != PackageManager.PERMISSION_GRANTED) {
2082                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2089        }
2090    }
2091
2092    static class DbBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        DbBinder(ActivityManagerService activityManagerService) {
2095            mActivityManagerService = activityManagerService;
2096        }
2097
2098        @Override
2099        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2100            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2101                    != PackageManager.PERMISSION_GRANTED) {
2102                pw.println("Permission Denial: can't dump dbinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            mActivityManagerService.dumpDbInfo(fd, pw, args);
2109        }
2110    }
2111
2112    static class CpuBinder extends Binder {
2113        ActivityManagerService mActivityManagerService;
2114        CpuBinder(ActivityManagerService activityManagerService) {
2115            mActivityManagerService = activityManagerService;
2116        }
2117
2118        @Override
2119        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2120            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2121                    != PackageManager.PERMISSION_GRANTED) {
2122                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2123                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2124                        + " without permission " + android.Manifest.permission.DUMP);
2125                return;
2126            }
2127
2128            synchronized (mActivityManagerService.mProcessCpuTracker) {
2129                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2130                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2131                        SystemClock.uptimeMillis()));
2132            }
2133        }
2134    }
2135
2136    public static final class Lifecycle extends SystemService {
2137        private final ActivityManagerService mService;
2138
2139        public Lifecycle(Context context) {
2140            super(context);
2141            mService = new ActivityManagerService(context);
2142        }
2143
2144        @Override
2145        public void onStart() {
2146            mService.start();
2147        }
2148
2149        public ActivityManagerService getService() {
2150            return mService;
2151        }
2152    }
2153
2154    // Note: This method is invoked on the main thread but may need to attach various
2155    // handlers to other threads.  So take care to be explicit about the looper.
2156    public ActivityManagerService(Context systemContext) {
2157        mContext = systemContext;
2158        mFactoryTest = FactoryTest.getMode();
2159        mSystemThread = ActivityThread.currentActivityThread();
2160
2161        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2162
2163        mHandlerThread = new ServiceThread(TAG,
2164                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2165        mHandlerThread.start();
2166        mHandler = new MainHandler(mHandlerThread.getLooper());
2167
2168        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2169                "foreground", BROADCAST_FG_TIMEOUT, false);
2170        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2171                "background", BROADCAST_BG_TIMEOUT, true);
2172        mBroadcastQueues[0] = mFgBroadcastQueue;
2173        mBroadcastQueues[1] = mBgBroadcastQueue;
2174
2175        mServices = new ActiveServices(this);
2176        mProviderMap = new ProviderMap(this);
2177
2178        // TODO: Move creation of battery stats service outside of activity manager service.
2179        File dataDir = Environment.getDataDirectory();
2180        File systemDir = new File(dataDir, "system");
2181        systemDir.mkdirs();
2182        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2183        mBatteryStatsService.getActiveStatistics().readLocked();
2184        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2185        mOnBattery = DEBUG_POWER ? true
2186                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2187        mBatteryStatsService.getActiveStatistics().setCallback(this);
2188
2189        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2190
2191        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2192
2193        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2194
2195        // User 0 is the first and only user that runs at boot.
2196        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2197        mUserLru.add(Integer.valueOf(0));
2198        updateStartedUserArrayLocked();
2199
2200        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2201            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2202
2203        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2204
2205        mConfiguration.setToDefaults();
2206        mConfiguration.locale = Locale.getDefault();
2207
2208        mConfigurationSeq = mConfiguration.seq = 1;
2209        mProcessCpuTracker.init();
2210
2211        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2212        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2213        mRecentTasks = new RecentTasks(this);
2214        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2215        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2216
2217        mProcessCpuThread = new Thread("CpuTracker") {
2218            @Override
2219            public void run() {
2220                while (true) {
2221                    try {
2222                        try {
2223                            synchronized(this) {
2224                                final long now = SystemClock.uptimeMillis();
2225                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2226                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2227                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2228                                //        + ", write delay=" + nextWriteDelay);
2229                                if (nextWriteDelay < nextCpuDelay) {
2230                                    nextCpuDelay = nextWriteDelay;
2231                                }
2232                                if (nextCpuDelay > 0) {
2233                                    mProcessCpuMutexFree.set(true);
2234                                    this.wait(nextCpuDelay);
2235                                }
2236                            }
2237                        } catch (InterruptedException e) {
2238                        }
2239                        updateCpuStatsNow();
2240                    } catch (Exception e) {
2241                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2242                    }
2243                }
2244            }
2245        };
2246
2247        Watchdog.getInstance().addMonitor(this);
2248        Watchdog.getInstance().addThread(mHandler);
2249    }
2250
2251    public void setSystemServiceManager(SystemServiceManager mgr) {
2252        mSystemServiceManager = mgr;
2253    }
2254
2255    public void setInstaller(Installer installer) {
2256        mInstaller = installer;
2257    }
2258
2259    private void start() {
2260        Process.removeAllProcessGroups();
2261        mProcessCpuThread.start();
2262
2263        mBatteryStatsService.publish(mContext);
2264        mAppOpsService.publish(mContext);
2265        Slog.d("AppOps", "AppOpsService published");
2266        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2267    }
2268
2269    public void initPowerManagement() {
2270        mStackSupervisor.initPowerManagement();
2271        mBatteryStatsService.initPowerManagement();
2272    }
2273
2274    @Override
2275    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2276            throws RemoteException {
2277        if (code == SYSPROPS_TRANSACTION) {
2278            // We need to tell all apps about the system property change.
2279            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2280            synchronized(this) {
2281                final int NP = mProcessNames.getMap().size();
2282                for (int ip=0; ip<NP; ip++) {
2283                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2284                    final int NA = apps.size();
2285                    for (int ia=0; ia<NA; ia++) {
2286                        ProcessRecord app = apps.valueAt(ia);
2287                        if (app.thread != null) {
2288                            procs.add(app.thread.asBinder());
2289                        }
2290                    }
2291                }
2292            }
2293
2294            int N = procs.size();
2295            for (int i=0; i<N; i++) {
2296                Parcel data2 = Parcel.obtain();
2297                try {
2298                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2299                } catch (RemoteException e) {
2300                }
2301                data2.recycle();
2302            }
2303        }
2304        try {
2305            return super.onTransact(code, data, reply, flags);
2306        } catch (RuntimeException e) {
2307            // The activity manager only throws security exceptions, so let's
2308            // log all others.
2309            if (!(e instanceof SecurityException)) {
2310                Slog.wtf(TAG, "Activity Manager Crash", e);
2311            }
2312            throw e;
2313        }
2314    }
2315
2316    void updateCpuStats() {
2317        final long now = SystemClock.uptimeMillis();
2318        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2319            return;
2320        }
2321        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2322            synchronized (mProcessCpuThread) {
2323                mProcessCpuThread.notify();
2324            }
2325        }
2326    }
2327
2328    void updateCpuStatsNow() {
2329        synchronized (mProcessCpuTracker) {
2330            mProcessCpuMutexFree.set(false);
2331            final long now = SystemClock.uptimeMillis();
2332            boolean haveNewCpuStats = false;
2333
2334            if (MONITOR_CPU_USAGE &&
2335                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2336                mLastCpuTime.set(now);
2337                mProcessCpuTracker.update();
2338                if (mProcessCpuTracker.hasGoodLastStats()) {
2339                    haveNewCpuStats = true;
2340                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2341                    //Slog.i(TAG, "Total CPU usage: "
2342                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2343
2344                    // Slog the cpu usage if the property is set.
2345                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2346                        int user = mProcessCpuTracker.getLastUserTime();
2347                        int system = mProcessCpuTracker.getLastSystemTime();
2348                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2349                        int irq = mProcessCpuTracker.getLastIrqTime();
2350                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2351                        int idle = mProcessCpuTracker.getLastIdleTime();
2352
2353                        int total = user + system + iowait + irq + softIrq + idle;
2354                        if (total == 0) total = 1;
2355
2356                        EventLog.writeEvent(EventLogTags.CPU,
2357                                ((user+system+iowait+irq+softIrq) * 100) / total,
2358                                (user * 100) / total,
2359                                (system * 100) / total,
2360                                (iowait * 100) / total,
2361                                (irq * 100) / total,
2362                                (softIrq * 100) / total);
2363                    }
2364                }
2365            }
2366
2367            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2368            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2369            synchronized(bstats) {
2370                synchronized(mPidsSelfLocked) {
2371                    if (haveNewCpuStats) {
2372                        final int perc = bstats.startAddingCpuLocked();
2373                        if (perc >= 0) {
2374                            int remainUTime = 0;
2375                            int remainSTime = 0;
2376                            int totalUTime = 0;
2377                            int totalSTime = 0;
2378                            final int N = mProcessCpuTracker.countStats();
2379                            for (int i=0; i<N; i++) {
2380                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2381                                if (!st.working) {
2382                                    continue;
2383                                }
2384                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2385                                int otherUTime = (st.rel_utime*perc)/100;
2386                                int otherSTime = (st.rel_stime*perc)/100;
2387                                remainUTime += otherUTime;
2388                                remainSTime += otherSTime;
2389                                totalUTime += st.rel_utime;
2390                                totalSTime += st.rel_stime;
2391                                if (pr != null) {
2392                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2393                                    if (ps == null || !ps.isActive()) {
2394                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2395                                                pr.info.uid, pr.processName);
2396                                    }
2397                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2398                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2399                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2400                                } else {
2401                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2402                                    if (ps == null || !ps.isActive()) {
2403                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2404                                                bstats.mapUid(st.uid), st.name);
2405                                    }
2406                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2407                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2408                                }
2409                            }
2410                            final int userTime = mProcessCpuTracker.getLastUserTime();
2411                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2412                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2413                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2414                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2415                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2416                            bstats.finishAddingCpuLocked(perc, remainUTime,
2417                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2418                                    iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
2419                        }
2420                    }
2421                }
2422
2423                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2424                    mLastWriteTime = now;
2425                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2426                }
2427            }
2428        }
2429    }
2430
2431    @Override
2432    public void batteryNeedsCpuUpdate() {
2433        updateCpuStatsNow();
2434    }
2435
2436    @Override
2437    public void batteryPowerChanged(boolean onBattery) {
2438        // When plugging in, update the CPU stats first before changing
2439        // the plug state.
2440        updateCpuStatsNow();
2441        synchronized (this) {
2442            synchronized(mPidsSelfLocked) {
2443                mOnBattery = DEBUG_POWER ? true : onBattery;
2444            }
2445        }
2446    }
2447
2448    /**
2449     * Initialize the application bind args. These are passed to each
2450     * process when the bindApplication() IPC is sent to the process. They're
2451     * lazily setup to make sure the services are running when they're asked for.
2452     */
2453    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2454        if (mAppBindArgs == null) {
2455            mAppBindArgs = new HashMap<>();
2456
2457            // Isolated processes won't get this optimization, so that we don't
2458            // violate the rules about which services they have access to.
2459            if (!isolated) {
2460                // Setup the application init args
2461                mAppBindArgs.put("package", ServiceManager.getService("package"));
2462                mAppBindArgs.put("window", ServiceManager.getService("window"));
2463                mAppBindArgs.put(Context.ALARM_SERVICE,
2464                        ServiceManager.getService(Context.ALARM_SERVICE));
2465            }
2466        }
2467        return mAppBindArgs;
2468    }
2469
2470    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2471        if (mFocusedActivity != r) {
2472            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2473            mFocusedActivity = r;
2474            if (r.task != null && r.task.voiceInteractor != null) {
2475                startRunningVoiceLocked();
2476            } else {
2477                finishRunningVoiceLocked();
2478            }
2479            if (r != null && mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2480                mWindowManager.setFocusedApp(r.appToken, true);
2481            }
2482            applyUpdateLockStateLocked(r);
2483        }
2484        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2485                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r, "setFocusedStack");
2503                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2504                }
2505            }
2506        }
2507    }
2508
2509    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2510    @Override
2511    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2512        synchronized (ActivityManagerService.this) {
2513            if (listener != null) {
2514                mTaskStackListeners.register(listener);
2515            }
2516        }
2517    }
2518
2519    @Override
2520    public void notifyActivityDrawn(IBinder token) {
2521        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2522        synchronized (this) {
2523            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2524            if (r != null) {
2525                r.task.stack.notifyActivityDrawnLocked(r);
2526            }
2527        }
2528    }
2529
2530    final void applyUpdateLockStateLocked(ActivityRecord r) {
2531        // Modifications to the UpdateLock state are done on our handler, outside
2532        // the activity manager's locks.  The new state is determined based on the
2533        // state *now* of the relevant activity record.  The object is passed to
2534        // the handler solely for logging detail, not to be consulted/modified.
2535        final boolean nextState = r != null && r.immersive;
2536        mHandler.sendMessage(
2537                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2538    }
2539
2540    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2541        Message msg = Message.obtain();
2542        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2543        msg.obj = r.task.askedCompatMode ? null : r;
2544        mHandler.sendMessage(msg);
2545    }
2546
2547    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2548            String what, Object obj, ProcessRecord srcApp) {
2549        app.lastActivityTime = now;
2550
2551        if (app.activities.size() > 0) {
2552            // Don't want to touch dependent processes that are hosting activities.
2553            return index;
2554        }
2555
2556        int lrui = mLruProcesses.lastIndexOf(app);
2557        if (lrui < 0) {
2558            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2559                    + what + " " + obj + " from " + srcApp);
2560            return index;
2561        }
2562
2563        if (lrui >= index) {
2564            // Don't want to cause this to move dependent processes *back* in the
2565            // list as if they were less frequently used.
2566            return index;
2567        }
2568
2569        if (lrui >= mLruProcessActivityStart) {
2570            // Don't want to touch dependent processes that are hosting activities.
2571            return index;
2572        }
2573
2574        mLruProcesses.remove(lrui);
2575        if (index > 0) {
2576            index--;
2577        }
2578        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2579                + " in LRU list: " + app);
2580        mLruProcesses.add(index, app);
2581        return index;
2582    }
2583
2584    final void removeLruProcessLocked(ProcessRecord app) {
2585        int lrui = mLruProcesses.lastIndexOf(app);
2586        if (lrui >= 0) {
2587            if (!app.killed) {
2588                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2589                Process.killProcessQuiet(app.pid);
2590                Process.killProcessGroup(app.info.uid, app.pid);
2591            }
2592            if (lrui <= mLruProcessActivityStart) {
2593                mLruProcessActivityStart--;
2594            }
2595            if (lrui <= mLruProcessServiceStart) {
2596                mLruProcessServiceStart--;
2597            }
2598            mLruProcesses.remove(lrui);
2599        }
2600    }
2601
2602    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2603            ProcessRecord client) {
2604        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2605                || app.treatLikeActivity;
2606        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2607        if (!activityChange && hasActivity) {
2608            // The process has activities, so we are only allowing activity-based adjustments
2609            // to move it.  It should be kept in the front of the list with other
2610            // processes that have activities, and we don't want those to change their
2611            // order except due to activity operations.
2612            return;
2613        }
2614
2615        mLruSeq++;
2616        final long now = SystemClock.uptimeMillis();
2617        app.lastActivityTime = now;
2618
2619        // First a quick reject: if the app is already at the position we will
2620        // put it, then there is nothing to do.
2621        if (hasActivity) {
2622            final int N = mLruProcesses.size();
2623            if (N > 0 && mLruProcesses.get(N-1) == app) {
2624                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2625                return;
2626            }
2627        } else {
2628            if (mLruProcessServiceStart > 0
2629                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2630                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2631                return;
2632            }
2633        }
2634
2635        int lrui = mLruProcesses.lastIndexOf(app);
2636
2637        if (app.persistent && lrui >= 0) {
2638            // We don't care about the position of persistent processes, as long as
2639            // they are in the list.
2640            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2641            return;
2642        }
2643
2644        /* In progress: compute new position first, so we can avoid doing work
2645           if the process is not actually going to move.  Not yet working.
2646        int addIndex;
2647        int nextIndex;
2648        boolean inActivity = false, inService = false;
2649        if (hasActivity) {
2650            // Process has activities, put it at the very tipsy-top.
2651            addIndex = mLruProcesses.size();
2652            nextIndex = mLruProcessServiceStart;
2653            inActivity = true;
2654        } else if (hasService) {
2655            // Process has services, put it at the top of the service list.
2656            addIndex = mLruProcessActivityStart;
2657            nextIndex = mLruProcessServiceStart;
2658            inActivity = true;
2659            inService = true;
2660        } else  {
2661            // Process not otherwise of interest, it goes to the top of the non-service area.
2662            addIndex = mLruProcessServiceStart;
2663            if (client != null) {
2664                int clientIndex = mLruProcesses.lastIndexOf(client);
2665                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2666                        + app);
2667                if (clientIndex >= 0 && addIndex > clientIndex) {
2668                    addIndex = clientIndex;
2669                }
2670            }
2671            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2672        }
2673
2674        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2675                + mLruProcessActivityStart + "): " + app);
2676        */
2677
2678        if (lrui >= 0) {
2679            if (lrui < mLruProcessActivityStart) {
2680                mLruProcessActivityStart--;
2681            }
2682            if (lrui < mLruProcessServiceStart) {
2683                mLruProcessServiceStart--;
2684            }
2685            /*
2686            if (addIndex > lrui) {
2687                addIndex--;
2688            }
2689            if (nextIndex > lrui) {
2690                nextIndex--;
2691            }
2692            */
2693            mLruProcesses.remove(lrui);
2694        }
2695
2696        /*
2697        mLruProcesses.add(addIndex, app);
2698        if (inActivity) {
2699            mLruProcessActivityStart++;
2700        }
2701        if (inService) {
2702            mLruProcessActivityStart++;
2703        }
2704        */
2705
2706        int nextIndex;
2707        if (hasActivity) {
2708            final int N = mLruProcesses.size();
2709            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2710                // Process doesn't have activities, but has clients with
2711                // activities...  move it up, but one below the top (the top
2712                // should always have a real activity).
2713                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2714                mLruProcesses.add(N-1, app);
2715                // To keep it from spamming the LRU list (by making a bunch of clients),
2716                // we will push down any other entries owned by the app.
2717                final int uid = app.info.uid;
2718                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2719                    ProcessRecord subProc = mLruProcesses.get(i);
2720                    if (subProc.info.uid == uid) {
2721                        // We want to push this one down the list.  If the process after
2722                        // it is for the same uid, however, don't do so, because we don't
2723                        // want them internally to be re-ordered.
2724                        if (mLruProcesses.get(i-1).info.uid != uid) {
2725                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2726                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2727                            ProcessRecord tmp = mLruProcesses.get(i);
2728                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2729                            mLruProcesses.set(i-1, tmp);
2730                            i--;
2731                        }
2732                    } else {
2733                        // A gap, we can stop here.
2734                        break;
2735                    }
2736                }
2737            } else {
2738                // Process has activities, put it at the very tipsy-top.
2739                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2740                mLruProcesses.add(app);
2741            }
2742            nextIndex = mLruProcessServiceStart;
2743        } else if (hasService) {
2744            // Process has services, put it at the top of the service list.
2745            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2746            mLruProcesses.add(mLruProcessActivityStart, app);
2747            nextIndex = mLruProcessServiceStart;
2748            mLruProcessActivityStart++;
2749        } else  {
2750            // Process not otherwise of interest, it goes to the top of the non-service area.
2751            int index = mLruProcessServiceStart;
2752            if (client != null) {
2753                // If there is a client, don't allow the process to be moved up higher
2754                // in the list than that client.
2755                int clientIndex = mLruProcesses.lastIndexOf(client);
2756                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2757                        + " when updating " + app);
2758                if (clientIndex <= lrui) {
2759                    // Don't allow the client index restriction to push it down farther in the
2760                    // list than it already is.
2761                    clientIndex = lrui;
2762                }
2763                if (clientIndex >= 0 && index > clientIndex) {
2764                    index = clientIndex;
2765                }
2766            }
2767            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2768            mLruProcesses.add(index, app);
2769            nextIndex = index-1;
2770            mLruProcessActivityStart++;
2771            mLruProcessServiceStart++;
2772        }
2773
2774        // If the app is currently using a content provider or service,
2775        // bump those processes as well.
2776        for (int j=app.connections.size()-1; j>=0; j--) {
2777            ConnectionRecord cr = app.connections.valueAt(j);
2778            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2779                    && cr.binding.service.app != null
2780                    && cr.binding.service.app.lruSeq != mLruSeq
2781                    && !cr.binding.service.app.persistent) {
2782                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2783                        "service connection", cr, app);
2784            }
2785        }
2786        for (int j=app.conProviders.size()-1; j>=0; j--) {
2787            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2788            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2789                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2790                        "provider reference", cpr, app);
2791            }
2792        }
2793    }
2794
2795    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2796        if (uid == Process.SYSTEM_UID) {
2797            // The system gets to run in any process.  If there are multiple
2798            // processes with the same uid, just pick the first (this
2799            // should never happen).
2800            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2801            if (procs == null) return null;
2802            final int N = procs.size();
2803            for (int i = 0; i < N; i++) {
2804                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2805            }
2806        }
2807        ProcessRecord proc = mProcessNames.get(processName, uid);
2808        if (false && proc != null && !keepIfLarge
2809                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2810                && proc.lastCachedPss >= 4000) {
2811            // Turn this condition on to cause killing to happen regularly, for testing.
2812            if (proc.baseProcessTracker != null) {
2813                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2814            }
2815            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2816        } else if (proc != null && !keepIfLarge
2817                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2818                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2819            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2820            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2821                if (proc.baseProcessTracker != null) {
2822                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2823                }
2824                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2825            }
2826        }
2827        return proc;
2828    }
2829
2830    void ensurePackageDexOpt(String packageName) {
2831        IPackageManager pm = AppGlobals.getPackageManager();
2832        try {
2833            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2834                mDidDexOpt = true;
2835            }
2836        } catch (RemoteException e) {
2837        }
2838    }
2839
2840    boolean isNextTransitionForward() {
2841        int transit = mWindowManager.getPendingAppTransition();
2842        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2843                || transit == AppTransition.TRANSIT_TASK_OPEN
2844                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2845    }
2846
2847    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2848            String processName, String abiOverride, int uid, Runnable crashHandler) {
2849        synchronized(this) {
2850            ApplicationInfo info = new ApplicationInfo();
2851            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2852            // For isolated processes, the former contains the parent's uid and the latter the
2853            // actual uid of the isolated process.
2854            // In the special case introduced by this method (which is, starting an isolated
2855            // process directly from the SystemServer without an actual parent app process) the
2856            // closest thing to a parent's uid is SYSTEM_UID.
2857            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2858            // the |isolated| logic in the ProcessRecord constructor.
2859            info.uid = Process.SYSTEM_UID;
2860            info.processName = processName;
2861            info.className = entryPoint;
2862            info.packageName = "android";
2863            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2864                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2865                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2866                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2867                    crashHandler);
2868            return proc != null ? proc.pid : 0;
2869        }
2870    }
2871
2872    final ProcessRecord startProcessLocked(String processName,
2873            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2874            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2875            boolean isolated, boolean keepIfLarge) {
2876        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2877                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2878                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2879                null /* crashHandler */);
2880    }
2881
2882    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2883            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2884            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2885            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2886        long startTime = SystemClock.elapsedRealtime();
2887        ProcessRecord app;
2888        if (!isolated) {
2889            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2890            checkTime(startTime, "startProcess: after getProcessRecord");
2891        } else {
2892            // If this is an isolated process, it can't re-use an existing process.
2893            app = null;
2894        }
2895        // We don't have to do anything more if:
2896        // (1) There is an existing application record; and
2897        // (2) The caller doesn't think it is dead, OR there is no thread
2898        //     object attached to it so we know it couldn't have crashed; and
2899        // (3) There is a pid assigned to it, so it is either starting or
2900        //     already running.
2901        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2902                + " app=" + app + " knownToBeDead=" + knownToBeDead
2903                + " thread=" + (app != null ? app.thread : null)
2904                + " pid=" + (app != null ? app.pid : -1));
2905        if (app != null && app.pid > 0) {
2906            if (!knownToBeDead || app.thread == null) {
2907                // We already have the app running, or are waiting for it to
2908                // come up (we have a pid but not yet its thread), so keep it.
2909                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2910                // If this is a new package in the process, add the package to the list
2911                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2912                checkTime(startTime, "startProcess: done, added package to proc");
2913                return app;
2914            }
2915
2916            // An application record is attached to a previous process,
2917            // clean it up now.
2918            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2919            checkTime(startTime, "startProcess: bad proc running, killing");
2920            Process.killProcessGroup(app.info.uid, app.pid);
2921            handleAppDiedLocked(app, true, true);
2922            checkTime(startTime, "startProcess: done killing old proc");
2923        }
2924
2925        String hostingNameStr = hostingName != null
2926                ? hostingName.flattenToShortString() : null;
2927
2928        if (!isolated) {
2929            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2930                // If we are in the background, then check to see if this process
2931                // is bad.  If so, we will just silently fail.
2932                if (mBadProcesses.get(info.processName, info.uid) != null) {
2933                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2934                            + "/" + info.processName);
2935                    return null;
2936                }
2937            } else {
2938                // When the user is explicitly starting a process, then clear its
2939                // crash count so that we won't make it bad until they see at
2940                // least one crash dialog again, and make the process good again
2941                // if it had been bad.
2942                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2943                        + "/" + info.processName);
2944                mProcessCrashTimes.remove(info.processName, info.uid);
2945                if (mBadProcesses.get(info.processName, info.uid) != null) {
2946                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2947                            UserHandle.getUserId(info.uid), info.uid,
2948                            info.processName);
2949                    mBadProcesses.remove(info.processName, info.uid);
2950                    if (app != null) {
2951                        app.bad = false;
2952                    }
2953                }
2954            }
2955        }
2956
2957        if (app == null) {
2958            checkTime(startTime, "startProcess: creating new process record");
2959            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2960            if (app == null) {
2961                Slog.w(TAG, "Failed making new process record for "
2962                        + processName + "/" + info.uid + " isolated=" + isolated);
2963                return null;
2964            }
2965            app.crashHandler = crashHandler;
2966            mProcessNames.put(processName, app.uid, app);
2967            if (isolated) {
2968                mIsolatedProcesses.put(app.uid, app);
2969            }
2970            checkTime(startTime, "startProcess: done creating new process record");
2971        } else {
2972            // If this is a new package in the process, add the package to the list
2973            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2974            checkTime(startTime, "startProcess: added package to existing proc");
2975        }
2976
2977        // If the system is not ready yet, then hold off on starting this
2978        // process until it is.
2979        if (!mProcessesReady
2980                && !isAllowedWhileBooting(info)
2981                && !allowWhileBooting) {
2982            if (!mProcessesOnHold.contains(app)) {
2983                mProcessesOnHold.add(app);
2984            }
2985            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2986            checkTime(startTime, "startProcess: returning with proc on hold");
2987            return app;
2988        }
2989
2990        checkTime(startTime, "startProcess: stepping in to startProcess");
2991        startProcessLocked(
2992                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2993        checkTime(startTime, "startProcess: done starting proc!");
2994        return (app.pid != 0) ? app : null;
2995    }
2996
2997    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2998        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2999    }
3000
3001    private final void startProcessLocked(ProcessRecord app,
3002            String hostingType, String hostingNameStr) {
3003        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3004                null /* entryPoint */, null /* entryPointArgs */);
3005    }
3006
3007    private final void startProcessLocked(ProcessRecord app, String hostingType,
3008            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3009        long startTime = SystemClock.elapsedRealtime();
3010        if (app.pid > 0 && app.pid != MY_PID) {
3011            checkTime(startTime, "startProcess: removing from pids map");
3012            synchronized (mPidsSelfLocked) {
3013                mPidsSelfLocked.remove(app.pid);
3014                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3015            }
3016            checkTime(startTime, "startProcess: done removing from pids map");
3017            app.setPid(0);
3018        }
3019
3020        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3021                "startProcessLocked removing on hold: " + app);
3022        mProcessesOnHold.remove(app);
3023
3024        checkTime(startTime, "startProcess: starting to update cpu stats");
3025        updateCpuStats();
3026        checkTime(startTime, "startProcess: done updating cpu stats");
3027
3028        try {
3029            int uid = app.uid;
3030
3031            int[] gids = null;
3032            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3033            if (!app.isolated) {
3034                int[] permGids = null;
3035                try {
3036                    checkTime(startTime, "startProcess: getting gids from package manager");
3037                    final PackageManager pm = mContext.getPackageManager();
3038                    permGids = pm.getPackageGids(app.info.packageName);
3039
3040                    if (Environment.isExternalStorageEmulated()) {
3041                        checkTime(startTime, "startProcess: checking external storage perm");
3042                        if (pm.checkPermission(
3043                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3044                                app.info.packageName) == PERMISSION_GRANTED) {
3045                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3046                        } else {
3047                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3048                        }
3049                    }
3050                } catch (PackageManager.NameNotFoundException e) {
3051                    Slog.w(TAG, "Unable to retrieve gids", e);
3052                }
3053
3054                /*
3055                 * Add shared application and profile GIDs so applications can share some
3056                 * resources like shared libraries and access user-wide resources
3057                 */
3058                if (permGids == null) {
3059                    gids = new int[2];
3060                } else {
3061                    gids = new int[permGids.length + 2];
3062                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3063                }
3064                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3065                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3066            }
3067            checkTime(startTime, "startProcess: building args");
3068            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3069                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3070                        && mTopComponent != null
3071                        && app.processName.equals(mTopComponent.getPackageName())) {
3072                    uid = 0;
3073                }
3074                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3075                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3076                    uid = 0;
3077                }
3078            }
3079            int debugFlags = 0;
3080            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3081                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3082                // Also turn on CheckJNI for debuggable apps. It's quite
3083                // awkward to turn on otherwise.
3084                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3085            }
3086            // Run the app in safe mode if its manifest requests so or the
3087            // system is booted in safe mode.
3088            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3089                mSafeMode == true) {
3090                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3091            }
3092            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3093                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3094            }
3095            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3096                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3097            }
3098            if ("1".equals(SystemProperties.get("debug.assert"))) {
3099                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3100            }
3101
3102            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3103            if (requiredAbi == null) {
3104                requiredAbi = Build.SUPPORTED_ABIS[0];
3105            }
3106
3107            String instructionSet = null;
3108            if (app.info.primaryCpuAbi != null) {
3109                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3110            }
3111
3112            app.gids = gids;
3113            app.requiredAbi = requiredAbi;
3114            app.instructionSet = instructionSet;
3115
3116            // Start the process.  It will either succeed and return a result containing
3117            // the PID of the new process, or else throw a RuntimeException.
3118            boolean isActivityProcess = (entryPoint == null);
3119            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3120            checkTime(startTime, "startProcess: asking zygote to start proc");
3121            Process.ProcessStartResult startResult = Process.start(entryPoint,
3122                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3123                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3124                    app.info.dataDir, entryPointArgs);
3125            checkTime(startTime, "startProcess: returned from zygote!");
3126
3127            if (app.isolated) {
3128                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3129            }
3130            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3131            checkTime(startTime, "startProcess: done updating battery stats");
3132
3133            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3134                    UserHandle.getUserId(uid), startResult.pid, uid,
3135                    app.processName, hostingType,
3136                    hostingNameStr != null ? hostingNameStr : "");
3137
3138            if (app.persistent) {
3139                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3140            }
3141
3142            checkTime(startTime, "startProcess: building log message");
3143            StringBuilder buf = mStringBuilder;
3144            buf.setLength(0);
3145            buf.append("Start proc ");
3146            buf.append(startResult.pid);
3147            buf.append(':');
3148            buf.append(app.processName);
3149            buf.append('/');
3150            UserHandle.formatUid(buf, uid);
3151            if (!isActivityProcess) {
3152                buf.append(" [");
3153                buf.append(entryPoint);
3154                buf.append("]");
3155            }
3156            buf.append(" for ");
3157            buf.append(hostingType);
3158            if (hostingNameStr != null) {
3159                buf.append(" ");
3160                buf.append(hostingNameStr);
3161            }
3162            Slog.i(TAG, buf.toString());
3163            app.setPid(startResult.pid);
3164            app.usingWrapper = startResult.usingWrapper;
3165            app.removed = false;
3166            app.killed = false;
3167            app.killedByAm = false;
3168            checkTime(startTime, "startProcess: starting to update pids map");
3169            synchronized (mPidsSelfLocked) {
3170                this.mPidsSelfLocked.put(startResult.pid, app);
3171                if (isActivityProcess) {
3172                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3173                    msg.obj = app;
3174                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3175                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3176                }
3177            }
3178            checkTime(startTime, "startProcess: done updating pids map");
3179        } catch (RuntimeException e) {
3180            // XXX do better error recovery.
3181            app.setPid(0);
3182            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3183            if (app.isolated) {
3184                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3185            }
3186            Slog.e(TAG, "Failure starting process " + app.processName, e);
3187        }
3188    }
3189
3190    void updateUsageStats(ActivityRecord component, boolean resumed) {
3191        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3192        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3193        if (resumed) {
3194            if (mUsageStatsService != null) {
3195                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3196                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3197            }
3198            synchronized (stats) {
3199                stats.noteActivityResumedLocked(component.app.uid);
3200            }
3201        } else {
3202            if (mUsageStatsService != null) {
3203                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3204                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3205            }
3206            synchronized (stats) {
3207                stats.noteActivityPausedLocked(component.app.uid);
3208            }
3209        }
3210    }
3211
3212    Intent getHomeIntent() {
3213        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3214        intent.setComponent(mTopComponent);
3215        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3216            intent.addCategory(Intent.CATEGORY_HOME);
3217        }
3218        return intent;
3219    }
3220
3221    boolean startHomeActivityLocked(int userId, String reason) {
3222        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3223                && mTopAction == null) {
3224            // We are running in factory test mode, but unable to find
3225            // the factory test app, so just sit around displaying the
3226            // error message and don't try to start anything.
3227            return false;
3228        }
3229        Intent intent = getHomeIntent();
3230        ActivityInfo aInfo =
3231            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3232        if (aInfo != null) {
3233            intent.setComponent(new ComponentName(
3234                    aInfo.applicationInfo.packageName, aInfo.name));
3235            // Don't do this if the home app is currently being
3236            // instrumented.
3237            aInfo = new ActivityInfo(aInfo);
3238            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3239            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3240                    aInfo.applicationInfo.uid, true);
3241            if (app == null || app.instrumentationClass == null) {
3242                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3243                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3244            }
3245        }
3246
3247        return true;
3248    }
3249
3250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3251        ActivityInfo ai = null;
3252        ComponentName comp = intent.getComponent();
3253        try {
3254            if (comp != null) {
3255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3256            } else {
3257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3258                        intent,
3259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3260                            flags, userId);
3261
3262                if (info != null) {
3263                    ai = info.activityInfo;
3264                }
3265            }
3266        } catch (RemoteException e) {
3267            // ignore
3268        }
3269
3270        return ai;
3271    }
3272
3273    /**
3274     * Starts the "new version setup screen" if appropriate.
3275     */
3276    void startSetupActivityLocked() {
3277        // Only do this once per boot.
3278        if (mCheckedForSetup) {
3279            return;
3280        }
3281
3282        // We will show this screen if the current one is a different
3283        // version than the last one shown, and we are not running in
3284        // low-level factory test mode.
3285        final ContentResolver resolver = mContext.getContentResolver();
3286        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3287                Settings.Global.getInt(resolver,
3288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3289            mCheckedForSetup = true;
3290
3291            // See if we should be showing the platform update setup UI.
3292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3293            List<ResolveInfo> ris = mContext.getPackageManager()
3294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3295
3296            // We don't allow third party apps to replace this.
3297            ResolveInfo ri = null;
3298            for (int i=0; ris != null && i<ris.size(); i++) {
3299                if ((ris.get(i).activityInfo.applicationInfo.flags
3300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3301                    ri = ris.get(i);
3302                    break;
3303                }
3304            }
3305
3306            if (ri != null) {
3307                String vers = ri.activityInfo.metaData != null
3308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3309                        : null;
3310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3312                            Intent.METADATA_SETUP_VERSION);
3313                }
3314                String lastVers = Settings.Secure.getString(
3315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3316                if (vers != null && !vers.equals(lastVers)) {
3317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3318                    intent.setComponent(new ComponentName(
3319                            ri.activityInfo.packageName, ri.activityInfo.name));
3320                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3321                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3322                            null);
3323                }
3324            }
3325        }
3326    }
3327
3328    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3329        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3330    }
3331
3332    void enforceNotIsolatedCaller(String caller) {
3333        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3334            throw new SecurityException("Isolated process not allowed to call " + caller);
3335        }
3336    }
3337
3338    void enforceShellRestriction(String restriction, int userHandle) {
3339        if (Binder.getCallingUid() == Process.SHELL_UID) {
3340            if (userHandle < 0
3341                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3342                throw new SecurityException("Shell does not have permission to access user "
3343                        + userHandle);
3344            }
3345        }
3346    }
3347
3348    @Override
3349    public int getFrontActivityScreenCompatMode() {
3350        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3351        synchronized (this) {
3352            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3353        }
3354    }
3355
3356    @Override
3357    public void setFrontActivityScreenCompatMode(int mode) {
3358        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3359                "setFrontActivityScreenCompatMode");
3360        synchronized (this) {
3361            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3362        }
3363    }
3364
3365    @Override
3366    public int getPackageScreenCompatMode(String packageName) {
3367        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3368        synchronized (this) {
3369            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3370        }
3371    }
3372
3373    @Override
3374    public void setPackageScreenCompatMode(String packageName, int mode) {
3375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3376                "setPackageScreenCompatMode");
3377        synchronized (this) {
3378            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3379        }
3380    }
3381
3382    @Override
3383    public boolean getPackageAskScreenCompat(String packageName) {
3384        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3385        synchronized (this) {
3386            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3387        }
3388    }
3389
3390    @Override
3391    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3392        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3393                "setPackageAskScreenCompat");
3394        synchronized (this) {
3395            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3396        }
3397    }
3398
3399    private void dispatchProcessesChanged() {
3400        int N;
3401        synchronized (this) {
3402            N = mPendingProcessChanges.size();
3403            if (mActiveProcessChanges.length < N) {
3404                mActiveProcessChanges = new ProcessChangeItem[N];
3405            }
3406            mPendingProcessChanges.toArray(mActiveProcessChanges);
3407            mAvailProcessChanges.addAll(mPendingProcessChanges);
3408            mPendingProcessChanges.clear();
3409            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3410        }
3411
3412        int i = mProcessObservers.beginBroadcast();
3413        while (i > 0) {
3414            i--;
3415            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3416            if (observer != null) {
3417                try {
3418                    for (int j=0; j<N; j++) {
3419                        ProcessChangeItem item = mActiveProcessChanges[j];
3420                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3421                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3422                                    + item.pid + " uid=" + item.uid + ": "
3423                                    + item.foregroundActivities);
3424                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3425                                    item.foregroundActivities);
3426                        }
3427                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3428                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3429                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3430                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3431                        }
3432                    }
3433                } catch (RemoteException e) {
3434                }
3435            }
3436        }
3437        mProcessObservers.finishBroadcast();
3438    }
3439
3440    private void dispatchProcessDied(int pid, int uid) {
3441        int i = mProcessObservers.beginBroadcast();
3442        while (i > 0) {
3443            i--;
3444            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3445            if (observer != null) {
3446                try {
3447                    observer.onProcessDied(pid, uid);
3448                } catch (RemoteException e) {
3449                }
3450            }
3451        }
3452        mProcessObservers.finishBroadcast();
3453    }
3454
3455    @Override
3456    public final int startActivity(IApplicationThread caller, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3458            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3459        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3460            resultWho, requestCode, startFlags, profilerInfo, options,
3461            UserHandle.getCallingUserId());
3462    }
3463
3464    @Override
3465    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3466            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3467            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3468        enforceNotIsolatedCaller("startActivity");
3469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3470                false, ALLOW_FULL_ONLY, "startActivity", null);
3471        // TODO: Switch to user app stacks here.
3472        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3473                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3474                profilerInfo, null, null, options, userId, null, null);
3475    }
3476
3477    @Override
3478    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3479            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3480            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3481
3482        // This is very dangerous -- it allows you to perform a start activity (including
3483        // permission grants) as any app that may launch one of your own activities.  So
3484        // we will only allow this to be done from activities that are part of the core framework,
3485        // and then only when they are running as the system.
3486        final ActivityRecord sourceRecord;
3487        final int targetUid;
3488        final String targetPackage;
3489        synchronized (this) {
3490            if (resultTo == null) {
3491                throw new SecurityException("Must be called from an activity");
3492            }
3493            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3494            if (sourceRecord == null) {
3495                throw new SecurityException("Called with bad activity token: " + resultTo);
3496            }
3497            if (!sourceRecord.info.packageName.equals("android")) {
3498                throw new SecurityException(
3499                        "Must be called from an activity that is declared in the android package");
3500            }
3501            if (sourceRecord.app == null) {
3502                throw new SecurityException("Called without a process attached to activity");
3503            }
3504            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3505                // This is still okay, as long as this activity is running under the
3506                // uid of the original calling activity.
3507                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3508                    throw new SecurityException(
3509                            "Calling activity in uid " + sourceRecord.app.uid
3510                                    + " must be system uid or original calling uid "
3511                                    + sourceRecord.launchedFromUid);
3512                }
3513            }
3514            targetUid = sourceRecord.launchedFromUid;
3515            targetPackage = sourceRecord.launchedFromPackage;
3516        }
3517
3518        if (userId == UserHandle.USER_NULL) {
3519            userId = UserHandle.getUserId(sourceRecord.app.uid);
3520        }
3521
3522        // TODO: Switch to user app stacks here.
3523        try {
3524            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3525                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3526                    null, null, options, userId, null, null);
3527            return ret;
3528        } catch (SecurityException e) {
3529            // XXX need to figure out how to propagate to original app.
3530            // A SecurityException here is generally actually a fault of the original
3531            // calling activity (such as a fairly granting permissions), so propagate it
3532            // back to them.
3533            /*
3534            StringBuilder msg = new StringBuilder();
3535            msg.append("While launching");
3536            msg.append(intent.toString());
3537            msg.append(": ");
3538            msg.append(e.getMessage());
3539            */
3540            throw e;
3541        }
3542    }
3543
3544    @Override
3545    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3546            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3547            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3548        enforceNotIsolatedCaller("startActivityAndWait");
3549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3550                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3551        WaitResult res = new WaitResult();
3552        // TODO: Switch to user app stacks here.
3553        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3554                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3555                options, userId, null, null);
3556        return res;
3557    }
3558
3559    @Override
3560    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3561            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3562            int startFlags, Configuration config, Bundle options, int userId) {
3563        enforceNotIsolatedCaller("startActivityWithConfig");
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3566        // TODO: Switch to user app stacks here.
3567        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3568                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3569                null, null, config, options, userId, null, null);
3570        return ret;
3571    }
3572
3573    @Override
3574    public int startActivityIntentSender(IApplicationThread caller,
3575            IntentSender intent, Intent fillInIntent, String resolvedType,
3576            IBinder resultTo, String resultWho, int requestCode,
3577            int flagsMask, int flagsValues, Bundle options) {
3578        enforceNotIsolatedCaller("startActivityIntentSender");
3579        // Refuse possible leaked file descriptors
3580        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3581            throw new IllegalArgumentException("File descriptors passed in Intent");
3582        }
3583
3584        IIntentSender sender = intent.getTarget();
3585        if (!(sender instanceof PendingIntentRecord)) {
3586            throw new IllegalArgumentException("Bad PendingIntent object");
3587        }
3588
3589        PendingIntentRecord pir = (PendingIntentRecord)sender;
3590
3591        synchronized (this) {
3592            // If this is coming from the currently resumed activity, it is
3593            // effectively saying that app switches are allowed at this point.
3594            final ActivityStack stack = getFocusedStack();
3595            if (stack.mResumedActivity != null &&
3596                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3597                mAppSwitchesAllowedTime = 0;
3598            }
3599        }
3600        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3601                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3602        return ret;
3603    }
3604
3605    @Override
3606    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3607            Intent intent, String resolvedType, IVoiceInteractionSession session,
3608            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3609            Bundle options, int userId) {
3610        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3611                != PackageManager.PERMISSION_GRANTED) {
3612            String msg = "Permission Denial: startVoiceActivity() from pid="
3613                    + Binder.getCallingPid()
3614                    + ", uid=" + Binder.getCallingUid()
3615                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3616            Slog.w(TAG, msg);
3617            throw new SecurityException(msg);
3618        }
3619        if (session == null || interactor == null) {
3620            throw new NullPointerException("null session or interactor");
3621        }
3622        userId = handleIncomingUser(callingPid, callingUid, userId,
3623                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3624        // TODO: Switch to user app stacks here.
3625        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3626                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3627                null, options, userId, null, null);
3628    }
3629
3630    @Override
3631    public boolean startNextMatchingActivity(IBinder callingActivity,
3632            Intent intent, Bundle options) {
3633        // Refuse possible leaked file descriptors
3634        if (intent != null && intent.hasFileDescriptors() == true) {
3635            throw new IllegalArgumentException("File descriptors passed in Intent");
3636        }
3637
3638        synchronized (this) {
3639            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3640            if (r == null) {
3641                ActivityOptions.abort(options);
3642                return false;
3643            }
3644            if (r.app == null || r.app.thread == null) {
3645                // The caller is not running...  d'oh!
3646                ActivityOptions.abort(options);
3647                return false;
3648            }
3649            intent = new Intent(intent);
3650            // The caller is not allowed to change the data.
3651            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3652            // And we are resetting to find the next component...
3653            intent.setComponent(null);
3654
3655            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3656
3657            ActivityInfo aInfo = null;
3658            try {
3659                List<ResolveInfo> resolves =
3660                    AppGlobals.getPackageManager().queryIntentActivities(
3661                            intent, r.resolvedType,
3662                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3663                            UserHandle.getCallingUserId());
3664
3665                // Look for the original activity in the list...
3666                final int N = resolves != null ? resolves.size() : 0;
3667                for (int i=0; i<N; i++) {
3668                    ResolveInfo rInfo = resolves.get(i);
3669                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3670                            && rInfo.activityInfo.name.equals(r.info.name)) {
3671                        // We found the current one...  the next matching is
3672                        // after it.
3673                        i++;
3674                        if (i<N) {
3675                            aInfo = resolves.get(i).activityInfo;
3676                        }
3677                        if (debug) {
3678                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3679                                    + "/" + r.info.name);
3680                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3681                                    + "/" + aInfo.name);
3682                        }
3683                        break;
3684                    }
3685                }
3686            } catch (RemoteException e) {
3687            }
3688
3689            if (aInfo == null) {
3690                // Nobody who is next!
3691                ActivityOptions.abort(options);
3692                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3693                return false;
3694            }
3695
3696            intent.setComponent(new ComponentName(
3697                    aInfo.applicationInfo.packageName, aInfo.name));
3698            intent.setFlags(intent.getFlags()&~(
3699                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3700                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3701                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3702                    Intent.FLAG_ACTIVITY_NEW_TASK));
3703
3704            // Okay now we need to start the new activity, replacing the
3705            // currently running activity.  This is a little tricky because
3706            // we want to start the new one as if the current one is finished,
3707            // but not finish the current one first so that there is no flicker.
3708            // And thus...
3709            final boolean wasFinishing = r.finishing;
3710            r.finishing = true;
3711
3712            // Propagate reply information over to the new activity.
3713            final ActivityRecord resultTo = r.resultTo;
3714            final String resultWho = r.resultWho;
3715            final int requestCode = r.requestCode;
3716            r.resultTo = null;
3717            if (resultTo != null) {
3718                resultTo.removeResultsLocked(r, resultWho, requestCode);
3719            }
3720
3721            final long origId = Binder.clearCallingIdentity();
3722            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3723                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3724                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3725                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3726            Binder.restoreCallingIdentity(origId);
3727
3728            r.finishing = wasFinishing;
3729            if (res != ActivityManager.START_SUCCESS) {
3730                return false;
3731            }
3732            return true;
3733        }
3734    }
3735
3736    @Override
3737    public final int startActivityFromRecents(int taskId, Bundle options) {
3738        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3739            String msg = "Permission Denial: startActivityFromRecents called without " +
3740                    START_TASKS_FROM_RECENTS;
3741            Slog.w(TAG, msg);
3742            throw new SecurityException(msg);
3743        }
3744        return startActivityFromRecentsInner(taskId, options);
3745    }
3746
3747    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3748        final TaskRecord task;
3749        final int callingUid;
3750        final String callingPackage;
3751        final Intent intent;
3752        final int userId;
3753        synchronized (this) {
3754            task = mRecentTasks.taskForIdLocked(taskId);
3755            if (task == null) {
3756                throw new IllegalArgumentException("Task " + taskId + " not found.");
3757            }
3758            if (task.getRootActivity() != null) {
3759                moveTaskToFrontLocked(task.taskId, 0, null);
3760                return ActivityManager.START_TASK_TO_FRONT;
3761            }
3762            callingUid = task.mCallingUid;
3763            callingPackage = task.mCallingPackage;
3764            intent = task.intent;
3765            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3766            userId = task.userId;
3767        }
3768        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3769                options, userId, null, task);
3770    }
3771
3772    final int startActivityInPackage(int uid, String callingPackage,
3773            Intent intent, String resolvedType, IBinder resultTo,
3774            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3775            IActivityContainer container, TaskRecord inTask) {
3776
3777        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3778                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3779
3780        // TODO: Switch to user app stacks here.
3781        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3782                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3783                null, null, null, options, userId, container, inTask);
3784        return ret;
3785    }
3786
3787    @Override
3788    public final int startActivities(IApplicationThread caller, String callingPackage,
3789            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3790            int userId) {
3791        enforceNotIsolatedCaller("startActivities");
3792        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3793                false, ALLOW_FULL_ONLY, "startActivity", null);
3794        // TODO: Switch to user app stacks here.
3795        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3796                resolvedTypes, resultTo, options, userId);
3797        return ret;
3798    }
3799
3800    final int startActivitiesInPackage(int uid, String callingPackage,
3801            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3802            Bundle options, int userId) {
3803
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3806        // TODO: Switch to user app stacks here.
3807        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3808                resultTo, options, userId);
3809        return ret;
3810    }
3811
3812    @Override
3813    public void reportActivityFullyDrawn(IBinder token) {
3814        synchronized (this) {
3815            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3816            if (r == null) {
3817                return;
3818            }
3819            r.reportFullyDrawnLocked();
3820        }
3821    }
3822
3823    @Override
3824    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3825        synchronized (this) {
3826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3827            if (r == null) {
3828                return;
3829            }
3830            if (r.task != null && r.task.mResizeable) {
3831                // Fixed screen orientation isn't supported with resizeable activities.
3832                return;
3833            }
3834            final long origId = Binder.clearCallingIdentity();
3835            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3836            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3837                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3838            if (config != null) {
3839                r.frozenBeforeDestroy = true;
3840                if (!updateConfigurationLocked(config, r, false, false)) {
3841                    mStackSupervisor.resumeTopActivitiesLocked();
3842                }
3843            }
3844            Binder.restoreCallingIdentity(origId);
3845        }
3846    }
3847
3848    @Override
3849    public int getRequestedOrientation(IBinder token) {
3850        synchronized (this) {
3851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3852            if (r == null) {
3853                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3854            }
3855            return mWindowManager.getAppOrientation(r.appToken);
3856        }
3857    }
3858
3859    /**
3860     * This is the internal entry point for handling Activity.finish().
3861     *
3862     * @param token The Binder token referencing the Activity we want to finish.
3863     * @param resultCode Result code, if any, from this Activity.
3864     * @param resultData Result data (Intent), if any, from this Activity.
3865     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3866     *            the root Activity in the task.
3867     *
3868     * @return Returns true if the activity successfully finished, or false if it is still running.
3869     */
3870    @Override
3871    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3872            boolean finishTask) {
3873        // Refuse possible leaked file descriptors
3874        if (resultData != null && resultData.hasFileDescriptors() == true) {
3875            throw new IllegalArgumentException("File descriptors passed in Intent");
3876        }
3877
3878        synchronized(this) {
3879            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3880            if (r == null) {
3881                return true;
3882            }
3883            // Keep track of the root activity of the task before we finish it
3884            TaskRecord tr = r.task;
3885            ActivityRecord rootR = tr.getRootActivity();
3886            if (rootR == null) {
3887                Slog.w(TAG, "Finishing task with all activities already finished");
3888            }
3889            // Do not allow task to finish in Lock Task mode.
3890            if (tr == mStackSupervisor.mLockTaskModeTask) {
3891                if (rootR == r) {
3892                    Slog.i(TAG, "Not finishing task in lock task mode");
3893                    mStackSupervisor.showLockTaskToast();
3894                    return false;
3895                }
3896            }
3897            if (mController != null) {
3898                // Find the first activity that is not finishing.
3899                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3900                if (next != null) {
3901                    // ask watcher if this is allowed
3902                    boolean resumeOK = true;
3903                    try {
3904                        resumeOK = mController.activityResuming(next.packageName);
3905                    } catch (RemoteException e) {
3906                        mController = null;
3907                        Watchdog.getInstance().setActivityController(null);
3908                    }
3909
3910                    if (!resumeOK) {
3911                        Slog.i(TAG, "Not finishing activity because controller resumed");
3912                        return false;
3913                    }
3914                }
3915            }
3916            final long origId = Binder.clearCallingIdentity();
3917            try {
3918                boolean res;
3919                if (finishTask && r == rootR) {
3920                    // If requested, remove the task that is associated to this activity only if it
3921                    // was the root activity in the task. The result code and data is ignored
3922                    // because we don't support returning them across task boundaries.
3923                    res = removeTaskByIdLocked(tr.taskId, false);
3924                    if (!res) {
3925                        Slog.i(TAG, "Removing task failed to finish activity");
3926                    }
3927                } else {
3928                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3929                            resultData, "app-request", true);
3930                    if (!res) {
3931                        Slog.i(TAG, "Failed to finish by app-request");
3932                    }
3933                }
3934                return res;
3935            } finally {
3936                Binder.restoreCallingIdentity(origId);
3937            }
3938        }
3939    }
3940
3941    @Override
3942    public final void finishHeavyWeightApp() {
3943        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3944                != PackageManager.PERMISSION_GRANTED) {
3945            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3946                    + Binder.getCallingPid()
3947                    + ", uid=" + Binder.getCallingUid()
3948                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3949            Slog.w(TAG, msg);
3950            throw new SecurityException(msg);
3951        }
3952
3953        synchronized(this) {
3954            if (mHeavyWeightProcess == null) {
3955                return;
3956            }
3957
3958            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3959                    mHeavyWeightProcess.activities);
3960            for (int i=0; i<activities.size(); i++) {
3961                ActivityRecord r = activities.get(i);
3962                if (!r.finishing) {
3963                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3964                            null, "finish-heavy", true);
3965                }
3966            }
3967
3968            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3969                    mHeavyWeightProcess.userId, 0));
3970            mHeavyWeightProcess = null;
3971        }
3972    }
3973
3974    @Override
3975    public void crashApplication(int uid, int initialPid, String packageName,
3976            String message) {
3977        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3978                != PackageManager.PERMISSION_GRANTED) {
3979            String msg = "Permission Denial: crashApplication() from pid="
3980                    + Binder.getCallingPid()
3981                    + ", uid=" + Binder.getCallingUid()
3982                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3983            Slog.w(TAG, msg);
3984            throw new SecurityException(msg);
3985        }
3986
3987        synchronized(this) {
3988            ProcessRecord proc = null;
3989
3990            // Figure out which process to kill.  We don't trust that initialPid
3991            // still has any relation to current pids, so must scan through the
3992            // list.
3993            synchronized (mPidsSelfLocked) {
3994                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3995                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3996                    if (p.uid != uid) {
3997                        continue;
3998                    }
3999                    if (p.pid == initialPid) {
4000                        proc = p;
4001                        break;
4002                    }
4003                    if (p.pkgList.containsKey(packageName)) {
4004                        proc = p;
4005                    }
4006                }
4007            }
4008
4009            if (proc == null) {
4010                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4011                        + " initialPid=" + initialPid
4012                        + " packageName=" + packageName);
4013                return;
4014            }
4015
4016            if (proc.thread != null) {
4017                if (proc.pid == Process.myPid()) {
4018                    Log.w(TAG, "crashApplication: trying to crash self!");
4019                    return;
4020                }
4021                long ident = Binder.clearCallingIdentity();
4022                try {
4023                    proc.thread.scheduleCrash(message);
4024                } catch (RemoteException e) {
4025                }
4026                Binder.restoreCallingIdentity(ident);
4027            }
4028        }
4029    }
4030
4031    @Override
4032    public final void finishSubActivity(IBinder token, String resultWho,
4033            int requestCode) {
4034        synchronized(this) {
4035            final long origId = Binder.clearCallingIdentity();
4036            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4037            if (r != null) {
4038                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4039            }
4040            Binder.restoreCallingIdentity(origId);
4041        }
4042    }
4043
4044    @Override
4045    public boolean finishActivityAffinity(IBinder token) {
4046        synchronized(this) {
4047            final long origId = Binder.clearCallingIdentity();
4048            try {
4049                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4050
4051                ActivityRecord rootR = r.task.getRootActivity();
4052                // Do not allow task to finish in Lock Task mode.
4053                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4054                    if (rootR == r) {
4055                        mStackSupervisor.showLockTaskToast();
4056                        return false;
4057                    }
4058                }
4059                boolean res = false;
4060                if (r != null) {
4061                    res = r.task.stack.finishActivityAffinityLocked(r);
4062                }
4063                return res;
4064            } finally {
4065                Binder.restoreCallingIdentity(origId);
4066            }
4067        }
4068    }
4069
4070    @Override
4071    public void finishVoiceTask(IVoiceInteractionSession session) {
4072        synchronized(this) {
4073            final long origId = Binder.clearCallingIdentity();
4074            try {
4075                mStackSupervisor.finishVoiceTask(session);
4076            } finally {
4077                Binder.restoreCallingIdentity(origId);
4078            }
4079        }
4080
4081    }
4082
4083    @Override
4084    public boolean releaseActivityInstance(IBinder token) {
4085        synchronized(this) {
4086            final long origId = Binder.clearCallingIdentity();
4087            try {
4088                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4089                if (r.task == null || r.task.stack == null) {
4090                    return false;
4091                }
4092                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4093            } finally {
4094                Binder.restoreCallingIdentity(origId);
4095            }
4096        }
4097    }
4098
4099    @Override
4100    public void releaseSomeActivities(IApplicationThread appInt) {
4101        synchronized(this) {
4102            final long origId = Binder.clearCallingIdentity();
4103            try {
4104                ProcessRecord app = getRecordForAppLocked(appInt);
4105                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4106            } finally {
4107                Binder.restoreCallingIdentity(origId);
4108            }
4109        }
4110    }
4111
4112    @Override
4113    public boolean willActivityBeVisible(IBinder token) {
4114        synchronized(this) {
4115            ActivityStack stack = ActivityRecord.getStackLocked(token);
4116            if (stack != null) {
4117                return stack.willActivityBeVisibleLocked(token);
4118            }
4119            return false;
4120        }
4121    }
4122
4123    @Override
4124    public void overridePendingTransition(IBinder token, String packageName,
4125            int enterAnim, int exitAnim) {
4126        synchronized(this) {
4127            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4128            if (self == null) {
4129                return;
4130            }
4131
4132            final long origId = Binder.clearCallingIdentity();
4133
4134            if (self.state == ActivityState.RESUMED
4135                    || self.state == ActivityState.PAUSING) {
4136                mWindowManager.overridePendingAppTransition(packageName,
4137                        enterAnim, exitAnim, null);
4138            }
4139
4140            Binder.restoreCallingIdentity(origId);
4141        }
4142    }
4143
4144    /**
4145     * Main function for removing an existing process from the activity manager
4146     * as a result of that process going away.  Clears out all connections
4147     * to the process.
4148     */
4149    private final void handleAppDiedLocked(ProcessRecord app,
4150            boolean restarting, boolean allowRestart) {
4151        int pid = app.pid;
4152        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4153        if (!kept && !restarting) {
4154            removeLruProcessLocked(app);
4155            if (pid > 0) {
4156                ProcessList.remove(pid);
4157            }
4158        }
4159
4160        if (mProfileProc == app) {
4161            clearProfilerLocked();
4162        }
4163
4164        // Remove this application's activities from active lists.
4165        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4166
4167        app.activities.clear();
4168
4169        if (app.instrumentationClass != null) {
4170            Slog.w(TAG, "Crash of app " + app.processName
4171                  + " running instrumentation " + app.instrumentationClass);
4172            Bundle info = new Bundle();
4173            info.putString("shortMsg", "Process crashed.");
4174            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4175        }
4176
4177        if (!restarting) {
4178            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4179                // If there was nothing to resume, and we are not already
4180                // restarting this process, but there is a visible activity that
4181                // is hosted by the process...  then make sure all visible
4182                // activities are running, taking care of restarting this
4183                // process.
4184                if (hasVisibleActivities) {
4185                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4186                }
4187            }
4188        }
4189    }
4190
4191    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4192        IBinder threadBinder = thread.asBinder();
4193        // Find the application record.
4194        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4195            ProcessRecord rec = mLruProcesses.get(i);
4196            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4197                return i;
4198            }
4199        }
4200        return -1;
4201    }
4202
4203    final ProcessRecord getRecordForAppLocked(
4204            IApplicationThread thread) {
4205        if (thread == null) {
4206            return null;
4207        }
4208
4209        int appIndex = getLRURecordIndexForAppLocked(thread);
4210        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4211    }
4212
4213    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4214        // If there are no longer any background processes running,
4215        // and the app that died was not running instrumentation,
4216        // then tell everyone we are now low on memory.
4217        boolean haveBg = false;
4218        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4219            ProcessRecord rec = mLruProcesses.get(i);
4220            if (rec.thread != null
4221                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4222                haveBg = true;
4223                break;
4224            }
4225        }
4226
4227        if (!haveBg) {
4228            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4229            if (doReport) {
4230                long now = SystemClock.uptimeMillis();
4231                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4232                    doReport = false;
4233                } else {
4234                    mLastMemUsageReportTime = now;
4235                }
4236            }
4237            final ArrayList<ProcessMemInfo> memInfos
4238                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4239            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4240            long now = SystemClock.uptimeMillis();
4241            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4242                ProcessRecord rec = mLruProcesses.get(i);
4243                if (rec == dyingProc || rec.thread == null) {
4244                    continue;
4245                }
4246                if (doReport) {
4247                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4248                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4249                }
4250                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4251                    // The low memory report is overriding any current
4252                    // state for a GC request.  Make sure to do
4253                    // heavy/important/visible/foreground processes first.
4254                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4255                        rec.lastRequestedGc = 0;
4256                    } else {
4257                        rec.lastRequestedGc = rec.lastLowMemory;
4258                    }
4259                    rec.reportLowMemory = true;
4260                    rec.lastLowMemory = now;
4261                    mProcessesToGc.remove(rec);
4262                    addProcessToGcListLocked(rec);
4263                }
4264            }
4265            if (doReport) {
4266                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4267                mHandler.sendMessage(msg);
4268            }
4269            scheduleAppGcsLocked();
4270        }
4271    }
4272
4273    final void appDiedLocked(ProcessRecord app) {
4274       appDiedLocked(app, app.pid, app.thread);
4275    }
4276
4277    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4278        // First check if this ProcessRecord is actually active for the pid.
4279        synchronized (mPidsSelfLocked) {
4280            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4281            if (curProc != app) {
4282                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4283                return;
4284            }
4285        }
4286
4287        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4288        synchronized (stats) {
4289            stats.noteProcessDiedLocked(app.info.uid, pid);
4290        }
4291
4292        if (!app.killed) {
4293            Process.killProcessQuiet(pid);
4294            Process.killProcessGroup(app.info.uid, pid);
4295            app.killed = true;
4296        }
4297
4298        // Clean up already done if the process has been re-started.
4299        if (app.pid == pid && app.thread != null &&
4300                app.thread.asBinder() == thread.asBinder()) {
4301            boolean doLowMem = app.instrumentationClass == null;
4302            boolean doOomAdj = doLowMem;
4303            if (!app.killedByAm) {
4304                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4305                        + ") has died");
4306                mAllowLowerMemLevel = true;
4307            } else {
4308                // Note that we always want to do oom adj to update our state with the
4309                // new number of procs.
4310                mAllowLowerMemLevel = false;
4311                doLowMem = false;
4312            }
4313            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4314            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4315                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4316            handleAppDiedLocked(app, false, true);
4317
4318            if (doOomAdj) {
4319                updateOomAdjLocked();
4320            }
4321            if (doLowMem) {
4322                doLowMemReportIfNeededLocked(app);
4323            }
4324        } else if (app.pid != pid) {
4325            // A new process has already been started.
4326            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4327                    + ") has died and restarted (pid " + app.pid + ").");
4328            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4329        } else if (DEBUG_PROCESSES) {
4330            Slog.d(TAG, "Received spurious death notification for thread "
4331                    + thread.asBinder());
4332        }
4333    }
4334
4335    /**
4336     * If a stack trace dump file is configured, dump process stack traces.
4337     * @param clearTraces causes the dump file to be erased prior to the new
4338     *    traces being written, if true; when false, the new traces will be
4339     *    appended to any existing file content.
4340     * @param firstPids of dalvik VM processes to dump stack traces for first
4341     * @param lastPids of dalvik VM processes to dump stack traces for last
4342     * @param nativeProcs optional list of native process names to dump stack crawls
4343     * @return file containing stack traces, or null if no dump file is configured
4344     */
4345    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4346            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4347        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4348        if (tracesPath == null || tracesPath.length() == 0) {
4349            return null;
4350        }
4351
4352        File tracesFile = new File(tracesPath);
4353        try {
4354            File tracesDir = tracesFile.getParentFile();
4355            if (!tracesDir.exists()) {
4356                tracesDir.mkdirs();
4357                if (!SELinux.restorecon(tracesDir)) {
4358                    return null;
4359                }
4360            }
4361            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4362
4363            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4364            tracesFile.createNewFile();
4365            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4366        } catch (IOException e) {
4367            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4368            return null;
4369        }
4370
4371        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4372        return tracesFile;
4373    }
4374
4375    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4376            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4377        // Use a FileObserver to detect when traces finish writing.
4378        // The order of traces is considered important to maintain for legibility.
4379        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4380            @Override
4381            public synchronized void onEvent(int event, String path) { notify(); }
4382        };
4383
4384        try {
4385            observer.startWatching();
4386
4387            // First collect all of the stacks of the most important pids.
4388            if (firstPids != null) {
4389                try {
4390                    int num = firstPids.size();
4391                    for (int i = 0; i < num; i++) {
4392                        synchronized (observer) {
4393                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4394                            observer.wait(200);  // Wait for write-close, give up after 200msec
4395                        }
4396                    }
4397                } catch (InterruptedException e) {
4398                    Slog.wtf(TAG, e);
4399                }
4400            }
4401
4402            // Next collect the stacks of the native pids
4403            if (nativeProcs != null) {
4404                int[] pids = Process.getPidsForCommands(nativeProcs);
4405                if (pids != null) {
4406                    for (int pid : pids) {
4407                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4408                    }
4409                }
4410            }
4411
4412            // Lastly, measure CPU usage.
4413            if (processCpuTracker != null) {
4414                processCpuTracker.init();
4415                System.gc();
4416                processCpuTracker.update();
4417                try {
4418                    synchronized (processCpuTracker) {
4419                        processCpuTracker.wait(500); // measure over 1/2 second.
4420                    }
4421                } catch (InterruptedException e) {
4422                }
4423                processCpuTracker.update();
4424
4425                // We'll take the stack crawls of just the top apps using CPU.
4426                final int N = processCpuTracker.countWorkingStats();
4427                int numProcs = 0;
4428                for (int i=0; i<N && numProcs<5; i++) {
4429                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4430                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4431                        numProcs++;
4432                        try {
4433                            synchronized (observer) {
4434                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4435                                observer.wait(200);  // Wait for write-close, give up after 200msec
4436                            }
4437                        } catch (InterruptedException e) {
4438                            Slog.wtf(TAG, e);
4439                        }
4440
4441                    }
4442                }
4443            }
4444        } finally {
4445            observer.stopWatching();
4446        }
4447    }
4448
4449    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4450        if (true || IS_USER_BUILD) {
4451            return;
4452        }
4453        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4454        if (tracesPath == null || tracesPath.length() == 0) {
4455            return;
4456        }
4457
4458        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4459        StrictMode.allowThreadDiskWrites();
4460        try {
4461            final File tracesFile = new File(tracesPath);
4462            final File tracesDir = tracesFile.getParentFile();
4463            final File tracesTmp = new File(tracesDir, "__tmp__");
4464            try {
4465                if (!tracesDir.exists()) {
4466                    tracesDir.mkdirs();
4467                    if (!SELinux.restorecon(tracesDir.getPath())) {
4468                        return;
4469                    }
4470                }
4471                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4472
4473                if (tracesFile.exists()) {
4474                    tracesTmp.delete();
4475                    tracesFile.renameTo(tracesTmp);
4476                }
4477                StringBuilder sb = new StringBuilder();
4478                Time tobj = new Time();
4479                tobj.set(System.currentTimeMillis());
4480                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4481                sb.append(": ");
4482                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4483                sb.append(" since ");
4484                sb.append(msg);
4485                FileOutputStream fos = new FileOutputStream(tracesFile);
4486                fos.write(sb.toString().getBytes());
4487                if (app == null) {
4488                    fos.write("\n*** No application process!".getBytes());
4489                }
4490                fos.close();
4491                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4492            } catch (IOException e) {
4493                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4494                return;
4495            }
4496
4497            if (app != null) {
4498                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4499                firstPids.add(app.pid);
4500                dumpStackTraces(tracesPath, firstPids, null, null, null);
4501            }
4502
4503            File lastTracesFile = null;
4504            File curTracesFile = null;
4505            for (int i=9; i>=0; i--) {
4506                String name = String.format(Locale.US, "slow%02d.txt", i);
4507                curTracesFile = new File(tracesDir, name);
4508                if (curTracesFile.exists()) {
4509                    if (lastTracesFile != null) {
4510                        curTracesFile.renameTo(lastTracesFile);
4511                    } else {
4512                        curTracesFile.delete();
4513                    }
4514                }
4515                lastTracesFile = curTracesFile;
4516            }
4517            tracesFile.renameTo(curTracesFile);
4518            if (tracesTmp.exists()) {
4519                tracesTmp.renameTo(tracesFile);
4520            }
4521        } finally {
4522            StrictMode.setThreadPolicy(oldPolicy);
4523        }
4524    }
4525
4526    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4527            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4528        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4529        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4530
4531        if (mController != null) {
4532            try {
4533                // 0 == continue, -1 = kill process immediately
4534                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4535                if (res < 0 && app.pid != MY_PID) {
4536                    app.kill("anr", true);
4537                }
4538            } catch (RemoteException e) {
4539                mController = null;
4540                Watchdog.getInstance().setActivityController(null);
4541            }
4542        }
4543
4544        long anrTime = SystemClock.uptimeMillis();
4545        if (MONITOR_CPU_USAGE) {
4546            updateCpuStatsNow();
4547        }
4548
4549        synchronized (this) {
4550            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4551            if (mShuttingDown) {
4552                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4553                return;
4554            } else if (app.notResponding) {
4555                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4556                return;
4557            } else if (app.crashing) {
4558                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4559                return;
4560            }
4561
4562            // In case we come through here for the same app before completing
4563            // this one, mark as anring now so we will bail out.
4564            app.notResponding = true;
4565
4566            // Log the ANR to the event log.
4567            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4568                    app.processName, app.info.flags, annotation);
4569
4570            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4571            firstPids.add(app.pid);
4572
4573            int parentPid = app.pid;
4574            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4575            if (parentPid != app.pid) firstPids.add(parentPid);
4576
4577            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4578
4579            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4580                ProcessRecord r = mLruProcesses.get(i);
4581                if (r != null && r.thread != null) {
4582                    int pid = r.pid;
4583                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4584                        if (r.persistent) {
4585                            firstPids.add(pid);
4586                        } else {
4587                            lastPids.put(pid, Boolean.TRUE);
4588                        }
4589                    }
4590                }
4591            }
4592        }
4593
4594        // Log the ANR to the main log.
4595        StringBuilder info = new StringBuilder();
4596        info.setLength(0);
4597        info.append("ANR in ").append(app.processName);
4598        if (activity != null && activity.shortComponentName != null) {
4599            info.append(" (").append(activity.shortComponentName).append(")");
4600        }
4601        info.append("\n");
4602        info.append("PID: ").append(app.pid).append("\n");
4603        if (annotation != null) {
4604            info.append("Reason: ").append(annotation).append("\n");
4605        }
4606        if (parent != null && parent != activity) {
4607            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4608        }
4609
4610        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4611
4612        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4613                NATIVE_STACKS_OF_INTEREST);
4614
4615        String cpuInfo = null;
4616        if (MONITOR_CPU_USAGE) {
4617            updateCpuStatsNow();
4618            synchronized (mProcessCpuTracker) {
4619                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4620            }
4621            info.append(processCpuTracker.printCurrentLoad());
4622            info.append(cpuInfo);
4623        }
4624
4625        info.append(processCpuTracker.printCurrentState(anrTime));
4626
4627        Slog.e(TAG, info.toString());
4628        if (tracesFile == null) {
4629            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4630            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4631        }
4632
4633        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4634                cpuInfo, tracesFile, null);
4635
4636        if (mController != null) {
4637            try {
4638                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4639                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4640                if (res != 0) {
4641                    if (res < 0 && app.pid != MY_PID) {
4642                        app.kill("anr", true);
4643                    } else {
4644                        synchronized (this) {
4645                            mServices.scheduleServiceTimeoutLocked(app);
4646                        }
4647                    }
4648                    return;
4649                }
4650            } catch (RemoteException e) {
4651                mController = null;
4652                Watchdog.getInstance().setActivityController(null);
4653            }
4654        }
4655
4656        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4657        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4658                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4659
4660        synchronized (this) {
4661            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4662
4663            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4664                app.kill("bg anr", true);
4665                return;
4666            }
4667
4668            // Set the app's notResponding state, and look up the errorReportReceiver
4669            makeAppNotRespondingLocked(app,
4670                    activity != null ? activity.shortComponentName : null,
4671                    annotation != null ? "ANR " + annotation : "ANR",
4672                    info.toString());
4673
4674            // Bring up the infamous App Not Responding dialog
4675            Message msg = Message.obtain();
4676            HashMap<String, Object> map = new HashMap<String, Object>();
4677            msg.what = SHOW_NOT_RESPONDING_MSG;
4678            msg.obj = map;
4679            msg.arg1 = aboveSystem ? 1 : 0;
4680            map.put("app", app);
4681            if (activity != null) {
4682                map.put("activity", activity);
4683            }
4684
4685            mHandler.sendMessage(msg);
4686        }
4687    }
4688
4689    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4690        if (!mLaunchWarningShown) {
4691            mLaunchWarningShown = true;
4692            mHandler.post(new Runnable() {
4693                @Override
4694                public void run() {
4695                    synchronized (ActivityManagerService.this) {
4696                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4697                        d.show();
4698                        mHandler.postDelayed(new Runnable() {
4699                            @Override
4700                            public void run() {
4701                                synchronized (ActivityManagerService.this) {
4702                                    d.dismiss();
4703                                    mLaunchWarningShown = false;
4704                                }
4705                            }
4706                        }, 4000);
4707                    }
4708                }
4709            });
4710        }
4711    }
4712
4713    @Override
4714    public boolean clearApplicationUserData(final String packageName,
4715            final IPackageDataObserver observer, int userId) {
4716        enforceNotIsolatedCaller("clearApplicationUserData");
4717        int uid = Binder.getCallingUid();
4718        int pid = Binder.getCallingPid();
4719        userId = handleIncomingUser(pid, uid,
4720                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4721        long callingId = Binder.clearCallingIdentity();
4722        try {
4723            IPackageManager pm = AppGlobals.getPackageManager();
4724            int pkgUid = -1;
4725            synchronized(this) {
4726                try {
4727                    pkgUid = pm.getPackageUid(packageName, userId);
4728                } catch (RemoteException e) {
4729                }
4730                if (pkgUid == -1) {
4731                    Slog.w(TAG, "Invalid packageName: " + packageName);
4732                    if (observer != null) {
4733                        try {
4734                            observer.onRemoveCompleted(packageName, false);
4735                        } catch (RemoteException e) {
4736                            Slog.i(TAG, "Observer no longer exists.");
4737                        }
4738                    }
4739                    return false;
4740                }
4741                if (uid == pkgUid || checkComponentPermission(
4742                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4743                        pid, uid, -1, true)
4744                        == PackageManager.PERMISSION_GRANTED) {
4745                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4746                } else {
4747                    throw new SecurityException("PID " + pid + " does not have permission "
4748                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4749                                    + " of package " + packageName);
4750                }
4751
4752                // Remove all tasks match the cleared application package and user
4753                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4754                    final TaskRecord tr = mRecentTasks.get(i);
4755                    final String taskPackageName =
4756                            tr.getBaseIntent().getComponent().getPackageName();
4757                    if (tr.userId != userId) continue;
4758                    if (!taskPackageName.equals(packageName)) continue;
4759                    removeTaskByIdLocked(tr.taskId, false);
4760                }
4761            }
4762
4763            try {
4764                // Clear application user data
4765                pm.clearApplicationUserData(packageName, observer, userId);
4766
4767                synchronized(this) {
4768                    // Remove all permissions granted from/to this package
4769                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4770                }
4771
4772                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4773                        Uri.fromParts("package", packageName, null));
4774                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4775                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4776                        null, null, 0, null, null, null, false, false, userId);
4777            } catch (RemoteException e) {
4778            }
4779        } finally {
4780            Binder.restoreCallingIdentity(callingId);
4781        }
4782        return true;
4783    }
4784
4785    @Override
4786    public void killBackgroundProcesses(final String packageName, int userId) {
4787        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4788                != PackageManager.PERMISSION_GRANTED &&
4789                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4790                        != PackageManager.PERMISSION_GRANTED) {
4791            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4792                    + Binder.getCallingPid()
4793                    + ", uid=" + Binder.getCallingUid()
4794                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4795            Slog.w(TAG, msg);
4796            throw new SecurityException(msg);
4797        }
4798
4799        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4800                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4801        long callingId = Binder.clearCallingIdentity();
4802        try {
4803            IPackageManager pm = AppGlobals.getPackageManager();
4804            synchronized(this) {
4805                int appId = -1;
4806                try {
4807                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4808                } catch (RemoteException e) {
4809                }
4810                if (appId == -1) {
4811                    Slog.w(TAG, "Invalid packageName: " + packageName);
4812                    return;
4813                }
4814                killPackageProcessesLocked(packageName, appId, userId,
4815                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4816            }
4817        } finally {
4818            Binder.restoreCallingIdentity(callingId);
4819        }
4820    }
4821
4822    @Override
4823    public void killAllBackgroundProcesses() {
4824        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4825                != PackageManager.PERMISSION_GRANTED) {
4826            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4827                    + Binder.getCallingPid()
4828                    + ", uid=" + Binder.getCallingUid()
4829                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4830            Slog.w(TAG, msg);
4831            throw new SecurityException(msg);
4832        }
4833
4834        long callingId = Binder.clearCallingIdentity();
4835        try {
4836            synchronized(this) {
4837                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4838                final int NP = mProcessNames.getMap().size();
4839                for (int ip=0; ip<NP; ip++) {
4840                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4841                    final int NA = apps.size();
4842                    for (int ia=0; ia<NA; ia++) {
4843                        ProcessRecord app = apps.valueAt(ia);
4844                        if (app.persistent) {
4845                            // we don't kill persistent processes
4846                            continue;
4847                        }
4848                        if (app.removed) {
4849                            procs.add(app);
4850                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4851                            app.removed = true;
4852                            procs.add(app);
4853                        }
4854                    }
4855                }
4856
4857                int N = procs.size();
4858                for (int i=0; i<N; i++) {
4859                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4860                }
4861                mAllowLowerMemLevel = true;
4862                updateOomAdjLocked();
4863                doLowMemReportIfNeededLocked(null);
4864            }
4865        } finally {
4866            Binder.restoreCallingIdentity(callingId);
4867        }
4868    }
4869
4870    @Override
4871    public void forceStopPackage(final String packageName, int userId) {
4872        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4873                != PackageManager.PERMISSION_GRANTED) {
4874            String msg = "Permission Denial: forceStopPackage() from pid="
4875                    + Binder.getCallingPid()
4876                    + ", uid=" + Binder.getCallingUid()
4877                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4878            Slog.w(TAG, msg);
4879            throw new SecurityException(msg);
4880        }
4881        final int callingPid = Binder.getCallingPid();
4882        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4883                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4884        long callingId = Binder.clearCallingIdentity();
4885        try {
4886            IPackageManager pm = AppGlobals.getPackageManager();
4887            synchronized(this) {
4888                int[] users = userId == UserHandle.USER_ALL
4889                        ? getUsersLocked() : new int[] { userId };
4890                for (int user : users) {
4891                    int pkgUid = -1;
4892                    try {
4893                        pkgUid = pm.getPackageUid(packageName, user);
4894                    } catch (RemoteException e) {
4895                    }
4896                    if (pkgUid == -1) {
4897                        Slog.w(TAG, "Invalid packageName: " + packageName);
4898                        continue;
4899                    }
4900                    try {
4901                        pm.setPackageStoppedState(packageName, true, user);
4902                    } catch (RemoteException e) {
4903                    } catch (IllegalArgumentException e) {
4904                        Slog.w(TAG, "Failed trying to unstop package "
4905                                + packageName + ": " + e);
4906                    }
4907                    if (isUserRunningLocked(user, false)) {
4908                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4909                    }
4910                }
4911            }
4912        } finally {
4913            Binder.restoreCallingIdentity(callingId);
4914        }
4915    }
4916
4917    @Override
4918    public void addPackageDependency(String packageName) {
4919        synchronized (this) {
4920            int callingPid = Binder.getCallingPid();
4921            if (callingPid == Process.myPid()) {
4922                //  Yeah, um, no.
4923                return;
4924            }
4925            ProcessRecord proc;
4926            synchronized (mPidsSelfLocked) {
4927                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4928            }
4929            if (proc != null) {
4930                if (proc.pkgDeps == null) {
4931                    proc.pkgDeps = new ArraySet<String>(1);
4932                }
4933                proc.pkgDeps.add(packageName);
4934            }
4935        }
4936    }
4937
4938    /*
4939     * The pkg name and app id have to be specified.
4940     */
4941    @Override
4942    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4943        if (pkg == null) {
4944            return;
4945        }
4946        // Make sure the uid is valid.
4947        if (appid < 0) {
4948            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4949            return;
4950        }
4951        int callerUid = Binder.getCallingUid();
4952        // Only the system server can kill an application
4953        if (callerUid == Process.SYSTEM_UID) {
4954            // Post an aysnc message to kill the application
4955            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4956            msg.arg1 = appid;
4957            msg.arg2 = 0;
4958            Bundle bundle = new Bundle();
4959            bundle.putString("pkg", pkg);
4960            bundle.putString("reason", reason);
4961            msg.obj = bundle;
4962            mHandler.sendMessage(msg);
4963        } else {
4964            throw new SecurityException(callerUid + " cannot kill pkg: " +
4965                    pkg);
4966        }
4967    }
4968
4969    @Override
4970    public void closeSystemDialogs(String reason) {
4971        enforceNotIsolatedCaller("closeSystemDialogs");
4972
4973        final int pid = Binder.getCallingPid();
4974        final int uid = Binder.getCallingUid();
4975        final long origId = Binder.clearCallingIdentity();
4976        try {
4977            synchronized (this) {
4978                // Only allow this from foreground processes, so that background
4979                // applications can't abuse it to prevent system UI from being shown.
4980                if (uid >= Process.FIRST_APPLICATION_UID) {
4981                    ProcessRecord proc;
4982                    synchronized (mPidsSelfLocked) {
4983                        proc = mPidsSelfLocked.get(pid);
4984                    }
4985                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4986                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4987                                + " from background process " + proc);
4988                        return;
4989                    }
4990                }
4991                closeSystemDialogsLocked(reason);
4992            }
4993        } finally {
4994            Binder.restoreCallingIdentity(origId);
4995        }
4996    }
4997
4998    void closeSystemDialogsLocked(String reason) {
4999        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5000        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5001                | Intent.FLAG_RECEIVER_FOREGROUND);
5002        if (reason != null) {
5003            intent.putExtra("reason", reason);
5004        }
5005        mWindowManager.closeSystemDialogs(reason);
5006
5007        mStackSupervisor.closeSystemDialogsLocked();
5008
5009        broadcastIntentLocked(null, null, intent, null,
5010                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5011                Process.SYSTEM_UID, UserHandle.USER_ALL);
5012    }
5013
5014    @Override
5015    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5016        enforceNotIsolatedCaller("getProcessMemoryInfo");
5017        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5018        for (int i=pids.length-1; i>=0; i--) {
5019            ProcessRecord proc;
5020            int oomAdj;
5021            synchronized (this) {
5022                synchronized (mPidsSelfLocked) {
5023                    proc = mPidsSelfLocked.get(pids[i]);
5024                    oomAdj = proc != null ? proc.setAdj : 0;
5025                }
5026            }
5027            infos[i] = new Debug.MemoryInfo();
5028            Debug.getMemoryInfo(pids[i], infos[i]);
5029            if (proc != null) {
5030                synchronized (this) {
5031                    if (proc.thread != null && proc.setAdj == oomAdj) {
5032                        // Record this for posterity if the process has been stable.
5033                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5034                                infos[i].getTotalUss(), false, proc.pkgList);
5035                    }
5036                }
5037            }
5038        }
5039        return infos;
5040    }
5041
5042    @Override
5043    public long[] getProcessPss(int[] pids) {
5044        enforceNotIsolatedCaller("getProcessPss");
5045        long[] pss = new long[pids.length];
5046        for (int i=pids.length-1; i>=0; i--) {
5047            ProcessRecord proc;
5048            int oomAdj;
5049            synchronized (this) {
5050                synchronized (mPidsSelfLocked) {
5051                    proc = mPidsSelfLocked.get(pids[i]);
5052                    oomAdj = proc != null ? proc.setAdj : 0;
5053                }
5054            }
5055            long[] tmpUss = new long[1];
5056            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5057            if (proc != null) {
5058                synchronized (this) {
5059                    if (proc.thread != null && proc.setAdj == oomAdj) {
5060                        // Record this for posterity if the process has been stable.
5061                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5062                    }
5063                }
5064            }
5065        }
5066        return pss;
5067    }
5068
5069    @Override
5070    public void killApplicationProcess(String processName, int uid) {
5071        if (processName == null) {
5072            return;
5073        }
5074
5075        int callerUid = Binder.getCallingUid();
5076        // Only the system server can kill an application
5077        if (callerUid == Process.SYSTEM_UID) {
5078            synchronized (this) {
5079                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5080                if (app != null && app.thread != null) {
5081                    try {
5082                        app.thread.scheduleSuicide();
5083                    } catch (RemoteException e) {
5084                        // If the other end already died, then our work here is done.
5085                    }
5086                } else {
5087                    Slog.w(TAG, "Process/uid not found attempting kill of "
5088                            + processName + " / " + uid);
5089                }
5090            }
5091        } else {
5092            throw new SecurityException(callerUid + " cannot kill app process: " +
5093                    processName);
5094        }
5095    }
5096
5097    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5098        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5099                false, true, false, false, UserHandle.getUserId(uid), reason);
5100        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5101                Uri.fromParts("package", packageName, null));
5102        if (!mProcessesReady) {
5103            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5104                    | Intent.FLAG_RECEIVER_FOREGROUND);
5105        }
5106        intent.putExtra(Intent.EXTRA_UID, uid);
5107        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5108        broadcastIntentLocked(null, null, intent,
5109                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5110                false, false,
5111                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5112    }
5113
5114    private void forceStopUserLocked(int userId, String reason) {
5115        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5116        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5117        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5118                | Intent.FLAG_RECEIVER_FOREGROUND);
5119        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5120        broadcastIntentLocked(null, null, intent,
5121                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5122                false, false,
5123                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5124    }
5125
5126    private final boolean killPackageProcessesLocked(String packageName, int appId,
5127            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5128            boolean doit, boolean evenPersistent, String reason) {
5129        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5130
5131        // Remove all processes this package may have touched: all with the
5132        // same UID (except for the system or root user), and all whose name
5133        // matches the package name.
5134        final int NP = mProcessNames.getMap().size();
5135        for (int ip=0; ip<NP; ip++) {
5136            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5137            final int NA = apps.size();
5138            for (int ia=0; ia<NA; ia++) {
5139                ProcessRecord app = apps.valueAt(ia);
5140                if (app.persistent && !evenPersistent) {
5141                    // we don't kill persistent processes
5142                    continue;
5143                }
5144                if (app.removed) {
5145                    if (doit) {
5146                        procs.add(app);
5147                    }
5148                    continue;
5149                }
5150
5151                // Skip process if it doesn't meet our oom adj requirement.
5152                if (app.setAdj < minOomAdj) {
5153                    continue;
5154                }
5155
5156                // If no package is specified, we call all processes under the
5157                // give user id.
5158                if (packageName == null) {
5159                    if (app.userId != userId) {
5160                        continue;
5161                    }
5162                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5163                        continue;
5164                    }
5165                // Package has been specified, we want to hit all processes
5166                // that match it.  We need to qualify this by the processes
5167                // that are running under the specified app and user ID.
5168                } else {
5169                    final boolean isDep = app.pkgDeps != null
5170                            && app.pkgDeps.contains(packageName);
5171                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5172                        continue;
5173                    }
5174                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5175                        continue;
5176                    }
5177                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5178                        continue;
5179                    }
5180                }
5181
5182                // Process has passed all conditions, kill it!
5183                if (!doit) {
5184                    return true;
5185                }
5186                app.removed = true;
5187                procs.add(app);
5188            }
5189        }
5190
5191        int N = procs.size();
5192        for (int i=0; i<N; i++) {
5193            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5194        }
5195        updateOomAdjLocked();
5196        return N > 0;
5197    }
5198
5199    private final boolean forceStopPackageLocked(String name, int appId,
5200            boolean callerWillRestart, boolean purgeCache, boolean doit,
5201            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5202        int i;
5203        int N;
5204
5205        if (userId == UserHandle.USER_ALL && name == null) {
5206            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5207        }
5208
5209        if (appId < 0 && name != null) {
5210            try {
5211                appId = UserHandle.getAppId(
5212                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5213            } catch (RemoteException e) {
5214            }
5215        }
5216
5217        if (doit) {
5218            if (name != null) {
5219                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5220                        + " user=" + userId + ": " + reason);
5221            } else {
5222                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5223            }
5224
5225            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5226            for (int ip=pmap.size()-1; ip>=0; ip--) {
5227                SparseArray<Long> ba = pmap.valueAt(ip);
5228                for (i=ba.size()-1; i>=0; i--) {
5229                    boolean remove = false;
5230                    final int entUid = ba.keyAt(i);
5231                    if (name != null) {
5232                        if (userId == UserHandle.USER_ALL) {
5233                            if (UserHandle.getAppId(entUid) == appId) {
5234                                remove = true;
5235                            }
5236                        } else {
5237                            if (entUid == UserHandle.getUid(userId, appId)) {
5238                                remove = true;
5239                            }
5240                        }
5241                    } else if (UserHandle.getUserId(entUid) == userId) {
5242                        remove = true;
5243                    }
5244                    if (remove) {
5245                        ba.removeAt(i);
5246                    }
5247                }
5248                if (ba.size() == 0) {
5249                    pmap.removeAt(ip);
5250                }
5251            }
5252        }
5253
5254        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5255                -100, callerWillRestart, true, doit, evenPersistent,
5256                name == null ? ("stop user " + userId) : ("stop " + name));
5257
5258        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5259            if (!doit) {
5260                return true;
5261            }
5262            didSomething = true;
5263        }
5264
5265        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5266            if (!doit) {
5267                return true;
5268            }
5269            didSomething = true;
5270        }
5271
5272        if (name == null) {
5273            // Remove all sticky broadcasts from this user.
5274            mStickyBroadcasts.remove(userId);
5275        }
5276
5277        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5278        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5279                userId, providers)) {
5280            if (!doit) {
5281                return true;
5282            }
5283            didSomething = true;
5284        }
5285        N = providers.size();
5286        for (i=0; i<N; i++) {
5287            removeDyingProviderLocked(null, providers.get(i), true);
5288        }
5289
5290        // Remove transient permissions granted from/to this package/user
5291        removeUriPermissionsForPackageLocked(name, userId, false);
5292
5293        if (name == null || uninstalling) {
5294            // Remove pending intents.  For now we only do this when force
5295            // stopping users, because we have some problems when doing this
5296            // for packages -- app widgets are not currently cleaned up for
5297            // such packages, so they can be left with bad pending intents.
5298            if (mIntentSenderRecords.size() > 0) {
5299                Iterator<WeakReference<PendingIntentRecord>> it
5300                        = mIntentSenderRecords.values().iterator();
5301                while (it.hasNext()) {
5302                    WeakReference<PendingIntentRecord> wpir = it.next();
5303                    if (wpir == null) {
5304                        it.remove();
5305                        continue;
5306                    }
5307                    PendingIntentRecord pir = wpir.get();
5308                    if (pir == null) {
5309                        it.remove();
5310                        continue;
5311                    }
5312                    if (name == null) {
5313                        // Stopping user, remove all objects for the user.
5314                        if (pir.key.userId != userId) {
5315                            // Not the same user, skip it.
5316                            continue;
5317                        }
5318                    } else {
5319                        if (UserHandle.getAppId(pir.uid) != appId) {
5320                            // Different app id, skip it.
5321                            continue;
5322                        }
5323                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5324                            // Different user, skip it.
5325                            continue;
5326                        }
5327                        if (!pir.key.packageName.equals(name)) {
5328                            // Different package, skip it.
5329                            continue;
5330                        }
5331                    }
5332                    if (!doit) {
5333                        return true;
5334                    }
5335                    didSomething = true;
5336                    it.remove();
5337                    pir.canceled = true;
5338                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5339                        pir.key.activity.pendingResults.remove(pir.ref);
5340                    }
5341                }
5342            }
5343        }
5344
5345        if (doit) {
5346            if (purgeCache && name != null) {
5347                AttributeCache ac = AttributeCache.instance();
5348                if (ac != null) {
5349                    ac.removePackage(name);
5350                }
5351            }
5352            if (mBooted) {
5353                mStackSupervisor.resumeTopActivitiesLocked();
5354                mStackSupervisor.scheduleIdleLocked();
5355            }
5356        }
5357
5358        return didSomething;
5359    }
5360
5361    private final boolean removeProcessLocked(ProcessRecord app,
5362            boolean callerWillRestart, boolean allowRestart, String reason) {
5363        final String name = app.processName;
5364        final int uid = app.uid;
5365        if (DEBUG_PROCESSES) Slog.d(
5366            TAG, "Force removing proc " + app.toShortString() + " (" + name
5367            + "/" + uid + ")");
5368
5369        mProcessNames.remove(name, uid);
5370        mIsolatedProcesses.remove(app.uid);
5371        if (mHeavyWeightProcess == app) {
5372            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5373                    mHeavyWeightProcess.userId, 0));
5374            mHeavyWeightProcess = null;
5375        }
5376        boolean needRestart = false;
5377        if (app.pid > 0 && app.pid != MY_PID) {
5378            int pid = app.pid;
5379            synchronized (mPidsSelfLocked) {
5380                mPidsSelfLocked.remove(pid);
5381                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5382            }
5383            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5384            if (app.isolated) {
5385                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5386            }
5387            app.kill(reason, true);
5388            handleAppDiedLocked(app, true, allowRestart);
5389            removeLruProcessLocked(app);
5390
5391            if (app.persistent && !app.isolated) {
5392                if (!callerWillRestart) {
5393                    addAppLocked(app.info, false, null /* ABI override */);
5394                } else {
5395                    needRestart = true;
5396                }
5397            }
5398        } else {
5399            mRemovedProcesses.add(app);
5400        }
5401
5402        return needRestart;
5403    }
5404
5405    private final void processStartTimedOutLocked(ProcessRecord app) {
5406        final int pid = app.pid;
5407        boolean gone = false;
5408        synchronized (mPidsSelfLocked) {
5409            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5410            if (knownApp != null && knownApp.thread == null) {
5411                mPidsSelfLocked.remove(pid);
5412                gone = true;
5413            }
5414        }
5415
5416        if (gone) {
5417            Slog.w(TAG, "Process " + app + " failed to attach");
5418            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5419                    pid, app.uid, app.processName);
5420            mProcessNames.remove(app.processName, app.uid);
5421            mIsolatedProcesses.remove(app.uid);
5422            if (mHeavyWeightProcess == app) {
5423                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5424                        mHeavyWeightProcess.userId, 0));
5425                mHeavyWeightProcess = null;
5426            }
5427            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5428            if (app.isolated) {
5429                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5430            }
5431            // Take care of any launching providers waiting for this process.
5432            checkAppInLaunchingProvidersLocked(app, true);
5433            // Take care of any services that are waiting for the process.
5434            mServices.processStartTimedOutLocked(app);
5435            app.kill("start timeout", true);
5436            removeLruProcessLocked(app);
5437            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5438                Slog.w(TAG, "Unattached app died before backup, skipping");
5439                try {
5440                    IBackupManager bm = IBackupManager.Stub.asInterface(
5441                            ServiceManager.getService(Context.BACKUP_SERVICE));
5442                    bm.agentDisconnected(app.info.packageName);
5443                } catch (RemoteException e) {
5444                    // Can't happen; the backup manager is local
5445                }
5446            }
5447            if (isPendingBroadcastProcessLocked(pid)) {
5448                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5449                skipPendingBroadcastLocked(pid);
5450            }
5451        } else {
5452            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5453        }
5454    }
5455
5456    private final boolean attachApplicationLocked(IApplicationThread thread,
5457            int pid) {
5458
5459        // Find the application record that is being attached...  either via
5460        // the pid if we are running in multiple processes, or just pull the
5461        // next app record if we are emulating process with anonymous threads.
5462        ProcessRecord app;
5463        if (pid != MY_PID && pid >= 0) {
5464            synchronized (mPidsSelfLocked) {
5465                app = mPidsSelfLocked.get(pid);
5466            }
5467        } else {
5468            app = null;
5469        }
5470
5471        if (app == null) {
5472            Slog.w(TAG, "No pending application record for pid " + pid
5473                    + " (IApplicationThread " + thread + "); dropping process");
5474            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5475            if (pid > 0 && pid != MY_PID) {
5476                Process.killProcessQuiet(pid);
5477                //TODO: Process.killProcessGroup(app.info.uid, pid);
5478            } else {
5479                try {
5480                    thread.scheduleExit();
5481                } catch (Exception e) {
5482                    // Ignore exceptions.
5483                }
5484            }
5485            return false;
5486        }
5487
5488        // If this application record is still attached to a previous
5489        // process, clean it up now.
5490        if (app.thread != null) {
5491            handleAppDiedLocked(app, true, true);
5492        }
5493
5494        // Tell the process all about itself.
5495
5496        if (DEBUG_ALL) Slog.v(
5497                TAG, "Binding process pid " + pid + " to record " + app);
5498
5499        final String processName = app.processName;
5500        try {
5501            AppDeathRecipient adr = new AppDeathRecipient(
5502                    app, pid, thread);
5503            thread.asBinder().linkToDeath(adr, 0);
5504            app.deathRecipient = adr;
5505        } catch (RemoteException e) {
5506            app.resetPackageList(mProcessStats);
5507            startProcessLocked(app, "link fail", processName);
5508            return false;
5509        }
5510
5511        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5512
5513        app.makeActive(thread, mProcessStats);
5514        app.curAdj = app.setAdj = -100;
5515        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5516        app.forcingToForeground = null;
5517        updateProcessForegroundLocked(app, false, false);
5518        app.hasShownUi = false;
5519        app.debugging = false;
5520        app.cached = false;
5521        app.killedByAm = false;
5522
5523        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5524
5525        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5526        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5527
5528        if (!normalMode) {
5529            Slog.i(TAG, "Launching preboot mode app: " + app);
5530        }
5531
5532        if (DEBUG_ALL) Slog.v(
5533            TAG, "New app record " + app
5534            + " thread=" + thread.asBinder() + " pid=" + pid);
5535        try {
5536            int testMode = IApplicationThread.DEBUG_OFF;
5537            if (mDebugApp != null && mDebugApp.equals(processName)) {
5538                testMode = mWaitForDebugger
5539                    ? IApplicationThread.DEBUG_WAIT
5540                    : IApplicationThread.DEBUG_ON;
5541                app.debugging = true;
5542                if (mDebugTransient) {
5543                    mDebugApp = mOrigDebugApp;
5544                    mWaitForDebugger = mOrigWaitForDebugger;
5545                }
5546            }
5547            String profileFile = app.instrumentationProfileFile;
5548            ParcelFileDescriptor profileFd = null;
5549            int samplingInterval = 0;
5550            boolean profileAutoStop = false;
5551            if (mProfileApp != null && mProfileApp.equals(processName)) {
5552                mProfileProc = app;
5553                profileFile = mProfileFile;
5554                profileFd = mProfileFd;
5555                samplingInterval = mSamplingInterval;
5556                profileAutoStop = mAutoStopProfiler;
5557            }
5558            boolean enableOpenGlTrace = false;
5559            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5560                enableOpenGlTrace = true;
5561                mOpenGlTraceApp = null;
5562            }
5563
5564            // If the app is being launched for restore or full backup, set it up specially
5565            boolean isRestrictedBackupMode = false;
5566            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5567                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5568                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5569                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5570            }
5571
5572            ensurePackageDexOpt(app.instrumentationInfo != null
5573                    ? app.instrumentationInfo.packageName
5574                    : app.info.packageName);
5575            if (app.instrumentationClass != null) {
5576                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5577            }
5578            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5579                    + processName + " with config " + mConfiguration);
5580            ApplicationInfo appInfo = app.instrumentationInfo != null
5581                    ? app.instrumentationInfo : app.info;
5582            app.compat = compatibilityInfoForPackageLocked(appInfo);
5583            if (profileFd != null) {
5584                profileFd = profileFd.dup();
5585            }
5586            ProfilerInfo profilerInfo = profileFile == null ? null
5587                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5588            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5589                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5590                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5591                    isRestrictedBackupMode || !normalMode, app.persistent,
5592                    new Configuration(mConfiguration), app.compat,
5593                    getCommonServicesLocked(app.isolated),
5594                    mCoreSettingsObserver.getCoreSettingsLocked());
5595            updateLruProcessLocked(app, false, null);
5596            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5597        } catch (Exception e) {
5598            // todo: Yikes!  What should we do?  For now we will try to
5599            // start another process, but that could easily get us in
5600            // an infinite loop of restarting processes...
5601            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5602
5603            app.resetPackageList(mProcessStats);
5604            app.unlinkDeathRecipient();
5605            startProcessLocked(app, "bind fail", processName);
5606            return false;
5607        }
5608
5609        // Remove this record from the list of starting applications.
5610        mPersistentStartingProcesses.remove(app);
5611        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5612                "Attach application locked removing on hold: " + app);
5613        mProcessesOnHold.remove(app);
5614
5615        boolean badApp = false;
5616        boolean didSomething = false;
5617
5618        // See if the top visible activity is waiting to run in this process...
5619        if (normalMode) {
5620            try {
5621                if (mStackSupervisor.attachApplicationLocked(app)) {
5622                    didSomething = true;
5623                }
5624            } catch (Exception e) {
5625                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5626                badApp = true;
5627            }
5628        }
5629
5630        // Find any services that should be running in this process...
5631        if (!badApp) {
5632            try {
5633                didSomething |= mServices.attachApplicationLocked(app, processName);
5634            } catch (Exception e) {
5635                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5636                badApp = true;
5637            }
5638        }
5639
5640        // Check if a next-broadcast receiver is in this process...
5641        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5642            try {
5643                didSomething |= sendPendingBroadcastsLocked(app);
5644            } catch (Exception e) {
5645                // If the app died trying to launch the receiver we declare it 'bad'
5646                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5647                badApp = true;
5648            }
5649        }
5650
5651        // Check whether the next backup agent is in this process...
5652        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5653            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
5654                    "New app is backup target, launching agent for " + app);
5655            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5656            try {
5657                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5658                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5659                        mBackupTarget.backupMode);
5660            } catch (Exception e) {
5661                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5662                badApp = true;
5663            }
5664        }
5665
5666        if (badApp) {
5667            app.kill("error during init", true);
5668            handleAppDiedLocked(app, false, true);
5669            return false;
5670        }
5671
5672        if (!didSomething) {
5673            updateOomAdjLocked();
5674        }
5675
5676        return true;
5677    }
5678
5679    @Override
5680    public final void attachApplication(IApplicationThread thread) {
5681        synchronized (this) {
5682            int callingPid = Binder.getCallingPid();
5683            final long origId = Binder.clearCallingIdentity();
5684            attachApplicationLocked(thread, callingPid);
5685            Binder.restoreCallingIdentity(origId);
5686        }
5687    }
5688
5689    @Override
5690    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5691        final long origId = Binder.clearCallingIdentity();
5692        synchronized (this) {
5693            ActivityStack stack = ActivityRecord.getStackLocked(token);
5694            if (stack != null) {
5695                ActivityRecord r =
5696                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5697                if (stopProfiling) {
5698                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5699                        try {
5700                            mProfileFd.close();
5701                        } catch (IOException e) {
5702                        }
5703                        clearProfilerLocked();
5704                    }
5705                }
5706            }
5707        }
5708        Binder.restoreCallingIdentity(origId);
5709    }
5710
5711    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5712        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5713                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5714    }
5715
5716    void enableScreenAfterBoot() {
5717        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5718                SystemClock.uptimeMillis());
5719        mWindowManager.enableScreenAfterBoot();
5720
5721        synchronized (this) {
5722            updateEventDispatchingLocked();
5723        }
5724    }
5725
5726    @Override
5727    public void showBootMessage(final CharSequence msg, final boolean always) {
5728        if (Binder.getCallingUid() != Process.myUid()) {
5729            // These days only the core system can call this, so apps can't get in
5730            // the way of what we show about running them.
5731        }
5732        mWindowManager.showBootMessage(msg, always);
5733    }
5734
5735    @Override
5736    public void keyguardWaitingForActivityDrawn() {
5737        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5738        final long token = Binder.clearCallingIdentity();
5739        try {
5740            synchronized (this) {
5741                if (DEBUG_LOCKSCREEN) logLockScreen("");
5742                mWindowManager.keyguardWaitingForActivityDrawn();
5743                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5744                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5745                    updateSleepIfNeededLocked();
5746                }
5747            }
5748        } finally {
5749            Binder.restoreCallingIdentity(token);
5750        }
5751    }
5752
5753    final void finishBooting() {
5754        synchronized (this) {
5755            if (!mBootAnimationComplete) {
5756                mCallFinishBooting = true;
5757                return;
5758            }
5759            mCallFinishBooting = false;
5760        }
5761
5762        ArraySet<String> completedIsas = new ArraySet<String>();
5763        for (String abi : Build.SUPPORTED_ABIS) {
5764            Process.establishZygoteConnectionForAbi(abi);
5765            final String instructionSet = VMRuntime.getInstructionSet(abi);
5766            if (!completedIsas.contains(instructionSet)) {
5767                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5768                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5769                }
5770                completedIsas.add(instructionSet);
5771            }
5772        }
5773
5774        IntentFilter pkgFilter = new IntentFilter();
5775        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5776        pkgFilter.addDataScheme("package");
5777        mContext.registerReceiver(new BroadcastReceiver() {
5778            @Override
5779            public void onReceive(Context context, Intent intent) {
5780                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5781                if (pkgs != null) {
5782                    for (String pkg : pkgs) {
5783                        synchronized (ActivityManagerService.this) {
5784                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5785                                    0, "query restart")) {
5786                                setResultCode(Activity.RESULT_OK);
5787                                return;
5788                            }
5789                        }
5790                    }
5791                }
5792            }
5793        }, pkgFilter);
5794
5795        IntentFilter dumpheapFilter = new IntentFilter();
5796        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
5797        mContext.registerReceiver(new BroadcastReceiver() {
5798            @Override
5799            public void onReceive(Context context, Intent intent) {
5800                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
5801                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
5802                } else {
5803                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
5804                }
5805            }
5806        }, dumpheapFilter);
5807
5808        // Let system services know.
5809        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5810
5811        synchronized (this) {
5812            // Ensure that any processes we had put on hold are now started
5813            // up.
5814            final int NP = mProcessesOnHold.size();
5815            if (NP > 0) {
5816                ArrayList<ProcessRecord> procs =
5817                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5818                for (int ip=0; ip<NP; ip++) {
5819                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5820                            + procs.get(ip));
5821                    startProcessLocked(procs.get(ip), "on-hold", null);
5822                }
5823            }
5824
5825            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5826                // Start looking for apps that are abusing wake locks.
5827                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5828                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5829                // Tell anyone interested that we are done booting!
5830                SystemProperties.set("sys.boot_completed", "1");
5831
5832                // And trigger dev.bootcomplete if we are not showing encryption progress
5833                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5834                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5835                    SystemProperties.set("dev.bootcomplete", "1");
5836                }
5837                for (int i=0; i<mStartedUsers.size(); i++) {
5838                    UserStartedState uss = mStartedUsers.valueAt(i);
5839                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5840                        uss.mState = UserStartedState.STATE_RUNNING;
5841                        final int userId = mStartedUsers.keyAt(i);
5842                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5843                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5844                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5845                        broadcastIntentLocked(null, null, intent, null,
5846                                new IIntentReceiver.Stub() {
5847                                    @Override
5848                                    public void performReceive(Intent intent, int resultCode,
5849                                            String data, Bundle extras, boolean ordered,
5850                                            boolean sticky, int sendingUser) {
5851                                        synchronized (ActivityManagerService.this) {
5852                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5853                                                    true, false);
5854                                        }
5855                                    }
5856                                },
5857                                0, null, null,
5858                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5859                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5860                                userId);
5861                    }
5862                }
5863                scheduleStartProfilesLocked();
5864            }
5865        }
5866    }
5867
5868    @Override
5869    public void bootAnimationComplete() {
5870        final boolean callFinishBooting;
5871        synchronized (this) {
5872            callFinishBooting = mCallFinishBooting;
5873            mBootAnimationComplete = true;
5874        }
5875        if (callFinishBooting) {
5876            finishBooting();
5877        }
5878    }
5879
5880    @Override
5881    public void systemBackupRestored() {
5882        synchronized (this) {
5883            if (mSystemReady) {
5884                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5885            } else {
5886                Slog.w(TAG, "System backup restored before system is ready");
5887            }
5888        }
5889    }
5890
5891    final void ensureBootCompleted() {
5892        boolean booting;
5893        boolean enableScreen;
5894        synchronized (this) {
5895            booting = mBooting;
5896            mBooting = false;
5897            enableScreen = !mBooted;
5898            mBooted = true;
5899        }
5900
5901        if (booting) {
5902            finishBooting();
5903        }
5904
5905        if (enableScreen) {
5906            enableScreenAfterBoot();
5907        }
5908    }
5909
5910    @Override
5911    public final void activityResumed(IBinder token) {
5912        final long origId = Binder.clearCallingIdentity();
5913        synchronized(this) {
5914            ActivityStack stack = ActivityRecord.getStackLocked(token);
5915            if (stack != null) {
5916                ActivityRecord.activityResumedLocked(token);
5917            }
5918        }
5919        Binder.restoreCallingIdentity(origId);
5920    }
5921
5922    @Override
5923    public final void activityPaused(IBinder token) {
5924        final long origId = Binder.clearCallingIdentity();
5925        synchronized(this) {
5926            ActivityStack stack = ActivityRecord.getStackLocked(token);
5927            if (stack != null) {
5928                stack.activityPausedLocked(token, false);
5929            }
5930        }
5931        Binder.restoreCallingIdentity(origId);
5932    }
5933
5934    @Override
5935    public final void activityStopped(IBinder token, Bundle icicle,
5936            PersistableBundle persistentState, CharSequence description) {
5937        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
5938
5939        // Refuse possible leaked file descriptors
5940        if (icicle != null && icicle.hasFileDescriptors()) {
5941            throw new IllegalArgumentException("File descriptors passed in Bundle");
5942        }
5943
5944        final long origId = Binder.clearCallingIdentity();
5945
5946        synchronized (this) {
5947            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5948            if (r != null) {
5949                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5950            }
5951        }
5952
5953        trimApplications();
5954
5955        Binder.restoreCallingIdentity(origId);
5956    }
5957
5958    @Override
5959    public final void activityDestroyed(IBinder token) {
5960        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5961        synchronized (this) {
5962            ActivityStack stack = ActivityRecord.getStackLocked(token);
5963            if (stack != null) {
5964                stack.activityDestroyedLocked(token, "activityDestroyed");
5965            }
5966        }
5967    }
5968
5969    @Override
5970    public final void backgroundResourcesReleased(IBinder token) {
5971        final long origId = Binder.clearCallingIdentity();
5972        try {
5973            synchronized (this) {
5974                ActivityStack stack = ActivityRecord.getStackLocked(token);
5975                if (stack != null) {
5976                    stack.backgroundResourcesReleased();
5977                }
5978            }
5979        } finally {
5980            Binder.restoreCallingIdentity(origId);
5981        }
5982    }
5983
5984    @Override
5985    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5986        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5987    }
5988
5989    @Override
5990    public final void notifyEnterAnimationComplete(IBinder token) {
5991        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5992    }
5993
5994    @Override
5995    public String getCallingPackage(IBinder token) {
5996        synchronized (this) {
5997            ActivityRecord r = getCallingRecordLocked(token);
5998            return r != null ? r.info.packageName : null;
5999        }
6000    }
6001
6002    @Override
6003    public ComponentName getCallingActivity(IBinder token) {
6004        synchronized (this) {
6005            ActivityRecord r = getCallingRecordLocked(token);
6006            return r != null ? r.intent.getComponent() : null;
6007        }
6008    }
6009
6010    private ActivityRecord getCallingRecordLocked(IBinder token) {
6011        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6012        if (r == null) {
6013            return null;
6014        }
6015        return r.resultTo;
6016    }
6017
6018    @Override
6019    public ComponentName getActivityClassForToken(IBinder token) {
6020        synchronized(this) {
6021            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6022            if (r == null) {
6023                return null;
6024            }
6025            return r.intent.getComponent();
6026        }
6027    }
6028
6029    @Override
6030    public String getPackageForToken(IBinder token) {
6031        synchronized(this) {
6032            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6033            if (r == null) {
6034                return null;
6035            }
6036            return r.packageName;
6037        }
6038    }
6039
6040    @Override
6041    public IIntentSender getIntentSender(int type,
6042            String packageName, IBinder token, String resultWho,
6043            int requestCode, Intent[] intents, String[] resolvedTypes,
6044            int flags, Bundle options, int userId) {
6045        enforceNotIsolatedCaller("getIntentSender");
6046        // Refuse possible leaked file descriptors
6047        if (intents != null) {
6048            if (intents.length < 1) {
6049                throw new IllegalArgumentException("Intents array length must be >= 1");
6050            }
6051            for (int i=0; i<intents.length; i++) {
6052                Intent intent = intents[i];
6053                if (intent != null) {
6054                    if (intent.hasFileDescriptors()) {
6055                        throw new IllegalArgumentException("File descriptors passed in Intent");
6056                    }
6057                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6058                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6059                        throw new IllegalArgumentException(
6060                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6061                    }
6062                    intents[i] = new Intent(intent);
6063                }
6064            }
6065            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6066                throw new IllegalArgumentException(
6067                        "Intent array length does not match resolvedTypes length");
6068            }
6069        }
6070        if (options != null) {
6071            if (options.hasFileDescriptors()) {
6072                throw new IllegalArgumentException("File descriptors passed in options");
6073            }
6074        }
6075
6076        synchronized(this) {
6077            int callingUid = Binder.getCallingUid();
6078            int origUserId = userId;
6079            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6080                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6081                    ALLOW_NON_FULL, "getIntentSender", null);
6082            if (origUserId == UserHandle.USER_CURRENT) {
6083                // We don't want to evaluate this until the pending intent is
6084                // actually executed.  However, we do want to always do the
6085                // security checking for it above.
6086                userId = UserHandle.USER_CURRENT;
6087            }
6088            try {
6089                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6090                    int uid = AppGlobals.getPackageManager()
6091                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6092                    if (!UserHandle.isSameApp(callingUid, uid)) {
6093                        String msg = "Permission Denial: getIntentSender() from pid="
6094                            + Binder.getCallingPid()
6095                            + ", uid=" + Binder.getCallingUid()
6096                            + ", (need uid=" + uid + ")"
6097                            + " is not allowed to send as package " + packageName;
6098                        Slog.w(TAG, msg);
6099                        throw new SecurityException(msg);
6100                    }
6101                }
6102
6103                return getIntentSenderLocked(type, packageName, callingUid, userId,
6104                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6105
6106            } catch (RemoteException e) {
6107                throw new SecurityException(e);
6108            }
6109        }
6110    }
6111
6112    IIntentSender getIntentSenderLocked(int type, String packageName,
6113            int callingUid, int userId, IBinder token, String resultWho,
6114            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6115            Bundle options) {
6116        if (DEBUG_MU)
6117            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6118        ActivityRecord activity = null;
6119        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6120            activity = ActivityRecord.isInStackLocked(token);
6121            if (activity == null) {
6122                return null;
6123            }
6124            if (activity.finishing) {
6125                return null;
6126            }
6127        }
6128
6129        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6130        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6131        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6132        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6133                |PendingIntent.FLAG_UPDATE_CURRENT);
6134
6135        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6136                type, packageName, activity, resultWho,
6137                requestCode, intents, resolvedTypes, flags, options, userId);
6138        WeakReference<PendingIntentRecord> ref;
6139        ref = mIntentSenderRecords.get(key);
6140        PendingIntentRecord rec = ref != null ? ref.get() : null;
6141        if (rec != null) {
6142            if (!cancelCurrent) {
6143                if (updateCurrent) {
6144                    if (rec.key.requestIntent != null) {
6145                        rec.key.requestIntent.replaceExtras(intents != null ?
6146                                intents[intents.length - 1] : null);
6147                    }
6148                    if (intents != null) {
6149                        intents[intents.length-1] = rec.key.requestIntent;
6150                        rec.key.allIntents = intents;
6151                        rec.key.allResolvedTypes = resolvedTypes;
6152                    } else {
6153                        rec.key.allIntents = null;
6154                        rec.key.allResolvedTypes = null;
6155                    }
6156                }
6157                return rec;
6158            }
6159            rec.canceled = true;
6160            mIntentSenderRecords.remove(key);
6161        }
6162        if (noCreate) {
6163            return rec;
6164        }
6165        rec = new PendingIntentRecord(this, key, callingUid);
6166        mIntentSenderRecords.put(key, rec.ref);
6167        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6168            if (activity.pendingResults == null) {
6169                activity.pendingResults
6170                        = new HashSet<WeakReference<PendingIntentRecord>>();
6171            }
6172            activity.pendingResults.add(rec.ref);
6173        }
6174        return rec;
6175    }
6176
6177    @Override
6178    public void cancelIntentSender(IIntentSender sender) {
6179        if (!(sender instanceof PendingIntentRecord)) {
6180            return;
6181        }
6182        synchronized(this) {
6183            PendingIntentRecord rec = (PendingIntentRecord)sender;
6184            try {
6185                int uid = AppGlobals.getPackageManager()
6186                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6187                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6188                    String msg = "Permission Denial: cancelIntentSender() from pid="
6189                        + Binder.getCallingPid()
6190                        + ", uid=" + Binder.getCallingUid()
6191                        + " is not allowed to cancel packges "
6192                        + rec.key.packageName;
6193                    Slog.w(TAG, msg);
6194                    throw new SecurityException(msg);
6195                }
6196            } catch (RemoteException e) {
6197                throw new SecurityException(e);
6198            }
6199            cancelIntentSenderLocked(rec, true);
6200        }
6201    }
6202
6203    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6204        rec.canceled = true;
6205        mIntentSenderRecords.remove(rec.key);
6206        if (cleanActivity && rec.key.activity != null) {
6207            rec.key.activity.pendingResults.remove(rec.ref);
6208        }
6209    }
6210
6211    @Override
6212    public String getPackageForIntentSender(IIntentSender pendingResult) {
6213        if (!(pendingResult instanceof PendingIntentRecord)) {
6214            return null;
6215        }
6216        try {
6217            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6218            return res.key.packageName;
6219        } catch (ClassCastException e) {
6220        }
6221        return null;
6222    }
6223
6224    @Override
6225    public int getUidForIntentSender(IIntentSender sender) {
6226        if (sender instanceof PendingIntentRecord) {
6227            try {
6228                PendingIntentRecord res = (PendingIntentRecord)sender;
6229                return res.uid;
6230            } catch (ClassCastException e) {
6231            }
6232        }
6233        return -1;
6234    }
6235
6236    @Override
6237    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6238        if (!(pendingResult instanceof PendingIntentRecord)) {
6239            return false;
6240        }
6241        try {
6242            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6243            if (res.key.allIntents == null) {
6244                return false;
6245            }
6246            for (int i=0; i<res.key.allIntents.length; i++) {
6247                Intent intent = res.key.allIntents[i];
6248                if (intent.getPackage() != null && intent.getComponent() != null) {
6249                    return false;
6250                }
6251            }
6252            return true;
6253        } catch (ClassCastException e) {
6254        }
6255        return false;
6256    }
6257
6258    @Override
6259    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6260        if (!(pendingResult instanceof PendingIntentRecord)) {
6261            return false;
6262        }
6263        try {
6264            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6265            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6266                return true;
6267            }
6268            return false;
6269        } catch (ClassCastException e) {
6270        }
6271        return false;
6272    }
6273
6274    @Override
6275    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6276        if (!(pendingResult instanceof PendingIntentRecord)) {
6277            return null;
6278        }
6279        try {
6280            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6281            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6282        } catch (ClassCastException e) {
6283        }
6284        return null;
6285    }
6286
6287    @Override
6288    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6289        if (!(pendingResult instanceof PendingIntentRecord)) {
6290            return null;
6291        }
6292        try {
6293            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6294            Intent intent = res.key.requestIntent;
6295            if (intent != null) {
6296                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6297                        || res.lastTagPrefix.equals(prefix))) {
6298                    return res.lastTag;
6299                }
6300                res.lastTagPrefix = prefix;
6301                StringBuilder sb = new StringBuilder(128);
6302                if (prefix != null) {
6303                    sb.append(prefix);
6304                }
6305                if (intent.getAction() != null) {
6306                    sb.append(intent.getAction());
6307                } else if (intent.getComponent() != null) {
6308                    intent.getComponent().appendShortString(sb);
6309                } else {
6310                    sb.append("?");
6311                }
6312                return res.lastTag = sb.toString();
6313            }
6314        } catch (ClassCastException e) {
6315        }
6316        return null;
6317    }
6318
6319    @Override
6320    public void setProcessLimit(int max) {
6321        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6322                "setProcessLimit()");
6323        synchronized (this) {
6324            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6325            mProcessLimitOverride = max;
6326        }
6327        trimApplications();
6328    }
6329
6330    @Override
6331    public int getProcessLimit() {
6332        synchronized (this) {
6333            return mProcessLimitOverride;
6334        }
6335    }
6336
6337    void foregroundTokenDied(ForegroundToken token) {
6338        synchronized (ActivityManagerService.this) {
6339            synchronized (mPidsSelfLocked) {
6340                ForegroundToken cur
6341                    = mForegroundProcesses.get(token.pid);
6342                if (cur != token) {
6343                    return;
6344                }
6345                mForegroundProcesses.remove(token.pid);
6346                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6347                if (pr == null) {
6348                    return;
6349                }
6350                pr.forcingToForeground = null;
6351                updateProcessForegroundLocked(pr, false, false);
6352            }
6353            updateOomAdjLocked();
6354        }
6355    }
6356
6357    @Override
6358    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6359        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6360                "setProcessForeground()");
6361        synchronized(this) {
6362            boolean changed = false;
6363
6364            synchronized (mPidsSelfLocked) {
6365                ProcessRecord pr = mPidsSelfLocked.get(pid);
6366                if (pr == null && isForeground) {
6367                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6368                    return;
6369                }
6370                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6371                if (oldToken != null) {
6372                    oldToken.token.unlinkToDeath(oldToken, 0);
6373                    mForegroundProcesses.remove(pid);
6374                    if (pr != null) {
6375                        pr.forcingToForeground = null;
6376                    }
6377                    changed = true;
6378                }
6379                if (isForeground && token != null) {
6380                    ForegroundToken newToken = new ForegroundToken() {
6381                        @Override
6382                        public void binderDied() {
6383                            foregroundTokenDied(this);
6384                        }
6385                    };
6386                    newToken.pid = pid;
6387                    newToken.token = token;
6388                    try {
6389                        token.linkToDeath(newToken, 0);
6390                        mForegroundProcesses.put(pid, newToken);
6391                        pr.forcingToForeground = token;
6392                        changed = true;
6393                    } catch (RemoteException e) {
6394                        // If the process died while doing this, we will later
6395                        // do the cleanup with the process death link.
6396                    }
6397                }
6398            }
6399
6400            if (changed) {
6401                updateOomAdjLocked();
6402            }
6403        }
6404    }
6405
6406    // =========================================================
6407    // PROCESS INFO
6408    // =========================================================
6409
6410    static class ProcessInfoService extends IProcessInfoService.Stub {
6411        final ActivityManagerService mActivityManagerService;
6412        ProcessInfoService(ActivityManagerService activityManagerService) {
6413            mActivityManagerService = activityManagerService;
6414        }
6415
6416        @Override
6417        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6418            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6419        }
6420    }
6421
6422    /**
6423     * For each PID in the given input array, write the current process state
6424     * for that process into the output array, or -1 to indicate that no
6425     * process with the given PID exists.
6426     */
6427    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6428        if (pids == null) {
6429            throw new NullPointerException("pids");
6430        } else if (states == null) {
6431            throw new NullPointerException("states");
6432        } else if (pids.length != states.length) {
6433            throw new IllegalArgumentException("input and output arrays have different lengths!");
6434        }
6435
6436        synchronized (mPidsSelfLocked) {
6437            for (int i = 0; i < pids.length; i++) {
6438                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6439                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6440                        pr.curProcState;
6441            }
6442        }
6443    }
6444
6445    // =========================================================
6446    // PERMISSIONS
6447    // =========================================================
6448
6449    static class PermissionController extends IPermissionController.Stub {
6450        ActivityManagerService mActivityManagerService;
6451        PermissionController(ActivityManagerService activityManagerService) {
6452            mActivityManagerService = activityManagerService;
6453        }
6454
6455        @Override
6456        public boolean checkPermission(String permission, int pid, int uid) {
6457            return mActivityManagerService.checkPermission(permission, pid,
6458                    uid) == PackageManager.PERMISSION_GRANTED;
6459        }
6460    }
6461
6462    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6463        @Override
6464        public int checkComponentPermission(String permission, int pid, int uid,
6465                int owningUid, boolean exported) {
6466            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6467                    owningUid, exported);
6468        }
6469
6470        @Override
6471        public Object getAMSLock() {
6472            return ActivityManagerService.this;
6473        }
6474    }
6475
6476    /**
6477     * This can be called with or without the global lock held.
6478     */
6479    int checkComponentPermission(String permission, int pid, int uid,
6480            int owningUid, boolean exported) {
6481        if (pid == MY_PID) {
6482            return PackageManager.PERMISSION_GRANTED;
6483        }
6484        return ActivityManager.checkComponentPermission(permission, uid,
6485                owningUid, exported);
6486    }
6487
6488    /**
6489     * As the only public entry point for permissions checking, this method
6490     * can enforce the semantic that requesting a check on a null global
6491     * permission is automatically denied.  (Internally a null permission
6492     * string is used when calling {@link #checkComponentPermission} in cases
6493     * when only uid-based security is needed.)
6494     *
6495     * This can be called with or without the global lock held.
6496     */
6497    @Override
6498    public int checkPermission(String permission, int pid, int uid) {
6499        if (permission == null) {
6500            return PackageManager.PERMISSION_DENIED;
6501        }
6502        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6503    }
6504
6505    @Override
6506    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6507        if (permission == null) {
6508            return PackageManager.PERMISSION_DENIED;
6509        }
6510
6511        // We might be performing an operation on behalf of an indirect binder
6512        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6513        // client identity accordingly before proceeding.
6514        Identity tlsIdentity = sCallerIdentity.get();
6515        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6516            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6517                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6518            uid = tlsIdentity.uid;
6519            pid = tlsIdentity.pid;
6520        }
6521
6522        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6523    }
6524
6525    /**
6526     * Binder IPC calls go through the public entry point.
6527     * This can be called with or without the global lock held.
6528     */
6529    int checkCallingPermission(String permission) {
6530        return checkPermission(permission,
6531                Binder.getCallingPid(),
6532                UserHandle.getAppId(Binder.getCallingUid()));
6533    }
6534
6535    /**
6536     * This can be called with or without the global lock held.
6537     */
6538    void enforceCallingPermission(String permission, String func) {
6539        if (checkCallingPermission(permission)
6540                == PackageManager.PERMISSION_GRANTED) {
6541            return;
6542        }
6543
6544        String msg = "Permission Denial: " + func + " from pid="
6545                + Binder.getCallingPid()
6546                + ", uid=" + Binder.getCallingUid()
6547                + " requires " + permission;
6548        Slog.w(TAG, msg);
6549        throw new SecurityException(msg);
6550    }
6551
6552    /**
6553     * Determine if UID is holding permissions required to access {@link Uri} in
6554     * the given {@link ProviderInfo}. Final permission checking is always done
6555     * in {@link ContentProvider}.
6556     */
6557    private final boolean checkHoldingPermissionsLocked(
6558            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6559        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6560                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6561        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6562            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6563                    != PERMISSION_GRANTED) {
6564                return false;
6565            }
6566        }
6567        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6568    }
6569
6570    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6571            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6572        if (pi.applicationInfo.uid == uid) {
6573            return true;
6574        } else if (!pi.exported) {
6575            return false;
6576        }
6577
6578        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6579        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6580        try {
6581            // check if target holds top-level <provider> permissions
6582            if (!readMet && pi.readPermission != null && considerUidPermissions
6583                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6584                readMet = true;
6585            }
6586            if (!writeMet && pi.writePermission != null && considerUidPermissions
6587                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6588                writeMet = true;
6589            }
6590
6591            // track if unprotected read/write is allowed; any denied
6592            // <path-permission> below removes this ability
6593            boolean allowDefaultRead = pi.readPermission == null;
6594            boolean allowDefaultWrite = pi.writePermission == null;
6595
6596            // check if target holds any <path-permission> that match uri
6597            final PathPermission[] pps = pi.pathPermissions;
6598            if (pps != null) {
6599                final String path = grantUri.uri.getPath();
6600                int i = pps.length;
6601                while (i > 0 && (!readMet || !writeMet)) {
6602                    i--;
6603                    PathPermission pp = pps[i];
6604                    if (pp.match(path)) {
6605                        if (!readMet) {
6606                            final String pprperm = pp.getReadPermission();
6607                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6608                                    + pprperm + " for " + pp.getPath()
6609                                    + ": match=" + pp.match(path)
6610                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6611                            if (pprperm != null) {
6612                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6613                                        == PERMISSION_GRANTED) {
6614                                    readMet = true;
6615                                } else {
6616                                    allowDefaultRead = false;
6617                                }
6618                            }
6619                        }
6620                        if (!writeMet) {
6621                            final String ppwperm = pp.getWritePermission();
6622                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6623                                    + ppwperm + " for " + pp.getPath()
6624                                    + ": match=" + pp.match(path)
6625                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6626                            if (ppwperm != null) {
6627                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6628                                        == PERMISSION_GRANTED) {
6629                                    writeMet = true;
6630                                } else {
6631                                    allowDefaultWrite = false;
6632                                }
6633                            }
6634                        }
6635                    }
6636                }
6637            }
6638
6639            // grant unprotected <provider> read/write, if not blocked by
6640            // <path-permission> above
6641            if (allowDefaultRead) readMet = true;
6642            if (allowDefaultWrite) writeMet = true;
6643
6644        } catch (RemoteException e) {
6645            return false;
6646        }
6647
6648        return readMet && writeMet;
6649    }
6650
6651    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6652        ProviderInfo pi = null;
6653        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6654        if (cpr != null) {
6655            pi = cpr.info;
6656        } else {
6657            try {
6658                pi = AppGlobals.getPackageManager().resolveContentProvider(
6659                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6660            } catch (RemoteException ex) {
6661            }
6662        }
6663        return pi;
6664    }
6665
6666    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6667        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6668        if (targetUris != null) {
6669            return targetUris.get(grantUri);
6670        }
6671        return null;
6672    }
6673
6674    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6675            String targetPkg, int targetUid, GrantUri grantUri) {
6676        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6677        if (targetUris == null) {
6678            targetUris = Maps.newArrayMap();
6679            mGrantedUriPermissions.put(targetUid, targetUris);
6680        }
6681
6682        UriPermission perm = targetUris.get(grantUri);
6683        if (perm == null) {
6684            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6685            targetUris.put(grantUri, perm);
6686        }
6687
6688        return perm;
6689    }
6690
6691    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6692            final int modeFlags) {
6693        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6694        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6695                : UriPermission.STRENGTH_OWNED;
6696
6697        // Root gets to do everything.
6698        if (uid == 0) {
6699            return true;
6700        }
6701
6702        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6703        if (perms == null) return false;
6704
6705        // First look for exact match
6706        final UriPermission exactPerm = perms.get(grantUri);
6707        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6708            return true;
6709        }
6710
6711        // No exact match, look for prefixes
6712        final int N = perms.size();
6713        for (int i = 0; i < N; i++) {
6714            final UriPermission perm = perms.valueAt(i);
6715            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6716                    && perm.getStrength(modeFlags) >= minStrength) {
6717                return true;
6718            }
6719        }
6720
6721        return false;
6722    }
6723
6724    /**
6725     * @param uri This uri must NOT contain an embedded userId.
6726     * @param userId The userId in which the uri is to be resolved.
6727     */
6728    @Override
6729    public int checkUriPermission(Uri uri, int pid, int uid,
6730            final int modeFlags, int userId, IBinder callerToken) {
6731        enforceNotIsolatedCaller("checkUriPermission");
6732
6733        // Another redirected-binder-call permissions check as in
6734        // {@link checkPermissionWithToken}.
6735        Identity tlsIdentity = sCallerIdentity.get();
6736        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6737            uid = tlsIdentity.uid;
6738            pid = tlsIdentity.pid;
6739        }
6740
6741        // Our own process gets to do everything.
6742        if (pid == MY_PID) {
6743            return PackageManager.PERMISSION_GRANTED;
6744        }
6745        synchronized (this) {
6746            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6747                    ? PackageManager.PERMISSION_GRANTED
6748                    : PackageManager.PERMISSION_DENIED;
6749        }
6750    }
6751
6752    /**
6753     * Check if the targetPkg can be granted permission to access uri by
6754     * the callingUid using the given modeFlags.  Throws a security exception
6755     * if callingUid is not allowed to do this.  Returns the uid of the target
6756     * if the URI permission grant should be performed; returns -1 if it is not
6757     * needed (for example targetPkg already has permission to access the URI).
6758     * If you already know the uid of the target, you can supply it in
6759     * lastTargetUid else set that to -1.
6760     */
6761    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6762            final int modeFlags, int lastTargetUid) {
6763        if (!Intent.isAccessUriMode(modeFlags)) {
6764            return -1;
6765        }
6766
6767        if (targetPkg != null) {
6768            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6769                    "Checking grant " + targetPkg + " permission to " + grantUri);
6770        }
6771
6772        final IPackageManager pm = AppGlobals.getPackageManager();
6773
6774        // If this is not a content: uri, we can't do anything with it.
6775        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6776            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6777                    "Can't grant URI permission for non-content URI: " + grantUri);
6778            return -1;
6779        }
6780
6781        final String authority = grantUri.uri.getAuthority();
6782        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6783        if (pi == null) {
6784            Slog.w(TAG, "No content provider found for permission check: " +
6785                    grantUri.uri.toSafeString());
6786            return -1;
6787        }
6788
6789        int targetUid = lastTargetUid;
6790        if (targetUid < 0 && targetPkg != null) {
6791            try {
6792                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6793                if (targetUid < 0) {
6794                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6795                            "Can't grant URI permission no uid for: " + targetPkg);
6796                    return -1;
6797                }
6798            } catch (RemoteException ex) {
6799                return -1;
6800            }
6801        }
6802
6803        if (targetUid >= 0) {
6804            // First...  does the target actually need this permission?
6805            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6806                // No need to grant the target this permission.
6807                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6808                        "Target " + targetPkg + " already has full permission to " + grantUri);
6809                return -1;
6810            }
6811        } else {
6812            // First...  there is no target package, so can anyone access it?
6813            boolean allowed = pi.exported;
6814            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6815                if (pi.readPermission != null) {
6816                    allowed = false;
6817                }
6818            }
6819            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6820                if (pi.writePermission != null) {
6821                    allowed = false;
6822                }
6823            }
6824            if (allowed) {
6825                return -1;
6826            }
6827        }
6828
6829        /* There is a special cross user grant if:
6830         * - The target is on another user.
6831         * - Apps on the current user can access the uri without any uid permissions.
6832         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6833         * grant uri permissions.
6834         */
6835        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6836                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6837                modeFlags, false /*without considering the uid permissions*/);
6838
6839        // Second...  is the provider allowing granting of URI permissions?
6840        if (!specialCrossUserGrant) {
6841            if (!pi.grantUriPermissions) {
6842                throw new SecurityException("Provider " + pi.packageName
6843                        + "/" + pi.name
6844                        + " does not allow granting of Uri permissions (uri "
6845                        + grantUri + ")");
6846            }
6847            if (pi.uriPermissionPatterns != null) {
6848                final int N = pi.uriPermissionPatterns.length;
6849                boolean allowed = false;
6850                for (int i=0; i<N; i++) {
6851                    if (pi.uriPermissionPatterns[i] != null
6852                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6853                        allowed = true;
6854                        break;
6855                    }
6856                }
6857                if (!allowed) {
6858                    throw new SecurityException("Provider " + pi.packageName
6859                            + "/" + pi.name
6860                            + " does not allow granting of permission to path of Uri "
6861                            + grantUri);
6862                }
6863            }
6864        }
6865
6866        // Third...  does the caller itself have permission to access
6867        // this uri?
6868        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6869            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6870                // Require they hold a strong enough Uri permission
6871                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6872                    throw new SecurityException("Uid " + callingUid
6873                            + " does not have permission to uri " + grantUri);
6874                }
6875            }
6876        }
6877        return targetUid;
6878    }
6879
6880    /**
6881     * @param uri This uri must NOT contain an embedded userId.
6882     * @param userId The userId in which the uri is to be resolved.
6883     */
6884    @Override
6885    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6886            final int modeFlags, int userId) {
6887        enforceNotIsolatedCaller("checkGrantUriPermission");
6888        synchronized(this) {
6889            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6890                    new GrantUri(userId, uri, false), modeFlags, -1);
6891        }
6892    }
6893
6894    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6895            final int modeFlags, UriPermissionOwner owner) {
6896        if (!Intent.isAccessUriMode(modeFlags)) {
6897            return;
6898        }
6899
6900        // So here we are: the caller has the assumed permission
6901        // to the uri, and the target doesn't.  Let's now give this to
6902        // the target.
6903
6904        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6905                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6906
6907        final String authority = grantUri.uri.getAuthority();
6908        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6909        if (pi == null) {
6910            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6911            return;
6912        }
6913
6914        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6915            grantUri.prefix = true;
6916        }
6917        final UriPermission perm = findOrCreateUriPermissionLocked(
6918                pi.packageName, targetPkg, targetUid, grantUri);
6919        perm.grantModes(modeFlags, owner);
6920    }
6921
6922    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6923            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6924        if (targetPkg == null) {
6925            throw new NullPointerException("targetPkg");
6926        }
6927        int targetUid;
6928        final IPackageManager pm = AppGlobals.getPackageManager();
6929        try {
6930            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6931        } catch (RemoteException ex) {
6932            return;
6933        }
6934
6935        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6936                targetUid);
6937        if (targetUid < 0) {
6938            return;
6939        }
6940
6941        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6942                owner);
6943    }
6944
6945    static class NeededUriGrants extends ArrayList<GrantUri> {
6946        final String targetPkg;
6947        final int targetUid;
6948        final int flags;
6949
6950        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6951            this.targetPkg = targetPkg;
6952            this.targetUid = targetUid;
6953            this.flags = flags;
6954        }
6955    }
6956
6957    /**
6958     * Like checkGrantUriPermissionLocked, but takes an Intent.
6959     */
6960    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6961            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6962        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6963                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6964                + " clip=" + (intent != null ? intent.getClipData() : null)
6965                + " from " + intent + "; flags=0x"
6966                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6967
6968        if (targetPkg == null) {
6969            throw new NullPointerException("targetPkg");
6970        }
6971
6972        if (intent == null) {
6973            return null;
6974        }
6975        Uri data = intent.getData();
6976        ClipData clip = intent.getClipData();
6977        if (data == null && clip == null) {
6978            return null;
6979        }
6980        // Default userId for uris in the intent (if they don't specify it themselves)
6981        int contentUserHint = intent.getContentUserHint();
6982        if (contentUserHint == UserHandle.USER_CURRENT) {
6983            contentUserHint = UserHandle.getUserId(callingUid);
6984        }
6985        final IPackageManager pm = AppGlobals.getPackageManager();
6986        int targetUid;
6987        if (needed != null) {
6988            targetUid = needed.targetUid;
6989        } else {
6990            try {
6991                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6992            } catch (RemoteException ex) {
6993                return null;
6994            }
6995            if (targetUid < 0) {
6996                if (DEBUG_URI_PERMISSION) {
6997                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6998                            + " on user " + targetUserId);
6999                }
7000                return null;
7001            }
7002        }
7003        if (data != null) {
7004            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7005            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7006                    targetUid);
7007            if (targetUid > 0) {
7008                if (needed == null) {
7009                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7010                }
7011                needed.add(grantUri);
7012            }
7013        }
7014        if (clip != null) {
7015            for (int i=0; i<clip.getItemCount(); i++) {
7016                Uri uri = clip.getItemAt(i).getUri();
7017                if (uri != null) {
7018                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7019                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7020                            targetUid);
7021                    if (targetUid > 0) {
7022                        if (needed == null) {
7023                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7024                        }
7025                        needed.add(grantUri);
7026                    }
7027                } else {
7028                    Intent clipIntent = clip.getItemAt(i).getIntent();
7029                    if (clipIntent != null) {
7030                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7031                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7032                        if (newNeeded != null) {
7033                            needed = newNeeded;
7034                        }
7035                    }
7036                }
7037            }
7038        }
7039
7040        return needed;
7041    }
7042
7043    /**
7044     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7045     */
7046    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7047            UriPermissionOwner owner) {
7048        if (needed != null) {
7049            for (int i=0; i<needed.size(); i++) {
7050                GrantUri grantUri = needed.get(i);
7051                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7052                        grantUri, needed.flags, owner);
7053            }
7054        }
7055    }
7056
7057    void grantUriPermissionFromIntentLocked(int callingUid,
7058            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7059        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7060                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7061        if (needed == null) {
7062            return;
7063        }
7064
7065        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7066    }
7067
7068    /**
7069     * @param uri This uri must NOT contain an embedded userId.
7070     * @param userId The userId in which the uri is to be resolved.
7071     */
7072    @Override
7073    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7074            final int modeFlags, int userId) {
7075        enforceNotIsolatedCaller("grantUriPermission");
7076        GrantUri grantUri = new GrantUri(userId, uri, false);
7077        synchronized(this) {
7078            final ProcessRecord r = getRecordForAppLocked(caller);
7079            if (r == null) {
7080                throw new SecurityException("Unable to find app for caller "
7081                        + caller
7082                        + " when granting permission to uri " + grantUri);
7083            }
7084            if (targetPkg == null) {
7085                throw new IllegalArgumentException("null target");
7086            }
7087            if (grantUri == null) {
7088                throw new IllegalArgumentException("null uri");
7089            }
7090
7091            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7092                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7093                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7094                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7095
7096            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7097                    UserHandle.getUserId(r.uid));
7098        }
7099    }
7100
7101    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7102        if (perm.modeFlags == 0) {
7103            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7104                    perm.targetUid);
7105            if (perms != null) {
7106                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7107                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7108
7109                perms.remove(perm.uri);
7110                if (perms.isEmpty()) {
7111                    mGrantedUriPermissions.remove(perm.targetUid);
7112                }
7113            }
7114        }
7115    }
7116
7117    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7118        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7119
7120        final IPackageManager pm = AppGlobals.getPackageManager();
7121        final String authority = grantUri.uri.getAuthority();
7122        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7123        if (pi == null) {
7124            Slog.w(TAG, "No content provider found for permission revoke: "
7125                    + grantUri.toSafeString());
7126            return;
7127        }
7128
7129        // Does the caller have this permission on the URI?
7130        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7131            // If they don't have direct access to the URI, then revoke any
7132            // ownerless URI permissions that have been granted to them.
7133            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7134            if (perms != null) {
7135                boolean persistChanged = false;
7136                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7137                    final UriPermission perm = it.next();
7138                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7139                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7140                        if (DEBUG_URI_PERMISSION)
7141                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7142                                    " permission to " + perm.uri);
7143                        persistChanged |= perm.revokeModes(
7144                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7145                        if (perm.modeFlags == 0) {
7146                            it.remove();
7147                        }
7148                    }
7149                }
7150                if (perms.isEmpty()) {
7151                    mGrantedUriPermissions.remove(callingUid);
7152                }
7153                if (persistChanged) {
7154                    schedulePersistUriGrants();
7155                }
7156            }
7157            return;
7158        }
7159
7160        boolean persistChanged = false;
7161
7162        // Go through all of the permissions and remove any that match.
7163        int N = mGrantedUriPermissions.size();
7164        for (int i = 0; i < N; i++) {
7165            final int targetUid = mGrantedUriPermissions.keyAt(i);
7166            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7167
7168            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7169                final UriPermission perm = it.next();
7170                if (perm.uri.sourceUserId == grantUri.sourceUserId
7171                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7172                    if (DEBUG_URI_PERMISSION)
7173                        Slog.v(TAG,
7174                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7175                    persistChanged |= perm.revokeModes(
7176                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7177                    if (perm.modeFlags == 0) {
7178                        it.remove();
7179                    }
7180                }
7181            }
7182
7183            if (perms.isEmpty()) {
7184                mGrantedUriPermissions.remove(targetUid);
7185                N--;
7186                i--;
7187            }
7188        }
7189
7190        if (persistChanged) {
7191            schedulePersistUriGrants();
7192        }
7193    }
7194
7195    /**
7196     * @param uri This uri must NOT contain an embedded userId.
7197     * @param userId The userId in which the uri is to be resolved.
7198     */
7199    @Override
7200    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7201            int userId) {
7202        enforceNotIsolatedCaller("revokeUriPermission");
7203        synchronized(this) {
7204            final ProcessRecord r = getRecordForAppLocked(caller);
7205            if (r == null) {
7206                throw new SecurityException("Unable to find app for caller "
7207                        + caller
7208                        + " when revoking permission to uri " + uri);
7209            }
7210            if (uri == null) {
7211                Slog.w(TAG, "revokeUriPermission: null uri");
7212                return;
7213            }
7214
7215            if (!Intent.isAccessUriMode(modeFlags)) {
7216                return;
7217            }
7218
7219            final String authority = uri.getAuthority();
7220            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7221            if (pi == null) {
7222                Slog.w(TAG, "No content provider found for permission revoke: "
7223                        + uri.toSafeString());
7224                return;
7225            }
7226
7227            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7228        }
7229    }
7230
7231    /**
7232     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7233     * given package.
7234     *
7235     * @param packageName Package name to match, or {@code null} to apply to all
7236     *            packages.
7237     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7238     *            to all users.
7239     * @param persistable If persistable grants should be removed.
7240     */
7241    private void removeUriPermissionsForPackageLocked(
7242            String packageName, int userHandle, boolean persistable) {
7243        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7244            throw new IllegalArgumentException("Must narrow by either package or user");
7245        }
7246
7247        boolean persistChanged = false;
7248
7249        int N = mGrantedUriPermissions.size();
7250        for (int i = 0; i < N; i++) {
7251            final int targetUid = mGrantedUriPermissions.keyAt(i);
7252            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7253
7254            // Only inspect grants matching user
7255            if (userHandle == UserHandle.USER_ALL
7256                    || userHandle == UserHandle.getUserId(targetUid)) {
7257                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7258                    final UriPermission perm = it.next();
7259
7260                    // Only inspect grants matching package
7261                    if (packageName == null || perm.sourcePkg.equals(packageName)
7262                            || perm.targetPkg.equals(packageName)) {
7263                        persistChanged |= perm.revokeModes(persistable
7264                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7265
7266                        // Only remove when no modes remain; any persisted grants
7267                        // will keep this alive.
7268                        if (perm.modeFlags == 0) {
7269                            it.remove();
7270                        }
7271                    }
7272                }
7273
7274                if (perms.isEmpty()) {
7275                    mGrantedUriPermissions.remove(targetUid);
7276                    N--;
7277                    i--;
7278                }
7279            }
7280        }
7281
7282        if (persistChanged) {
7283            schedulePersistUriGrants();
7284        }
7285    }
7286
7287    @Override
7288    public IBinder newUriPermissionOwner(String name) {
7289        enforceNotIsolatedCaller("newUriPermissionOwner");
7290        synchronized(this) {
7291            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7292            return owner.getExternalTokenLocked();
7293        }
7294    }
7295
7296    /**
7297     * @param uri This uri must NOT contain an embedded userId.
7298     * @param sourceUserId The userId in which the uri is to be resolved.
7299     * @param targetUserId The userId of the app that receives the grant.
7300     */
7301    @Override
7302    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7303            final int modeFlags, int sourceUserId, int targetUserId) {
7304        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7305                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7306        synchronized(this) {
7307            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7308            if (owner == null) {
7309                throw new IllegalArgumentException("Unknown owner: " + token);
7310            }
7311            if (fromUid != Binder.getCallingUid()) {
7312                if (Binder.getCallingUid() != Process.myUid()) {
7313                    // Only system code can grant URI permissions on behalf
7314                    // of other users.
7315                    throw new SecurityException("nice try");
7316                }
7317            }
7318            if (targetPkg == null) {
7319                throw new IllegalArgumentException("null target");
7320            }
7321            if (uri == null) {
7322                throw new IllegalArgumentException("null uri");
7323            }
7324
7325            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7326                    modeFlags, owner, targetUserId);
7327        }
7328    }
7329
7330    /**
7331     * @param uri This uri must NOT contain an embedded userId.
7332     * @param userId The userId in which the uri is to be resolved.
7333     */
7334    @Override
7335    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7336        synchronized(this) {
7337            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7338            if (owner == null) {
7339                throw new IllegalArgumentException("Unknown owner: " + token);
7340            }
7341
7342            if (uri == null) {
7343                owner.removeUriPermissionsLocked(mode);
7344            } else {
7345                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7346            }
7347        }
7348    }
7349
7350    private void schedulePersistUriGrants() {
7351        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7352            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7353                    10 * DateUtils.SECOND_IN_MILLIS);
7354        }
7355    }
7356
7357    private void writeGrantedUriPermissions() {
7358        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7359
7360        // Snapshot permissions so we can persist without lock
7361        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7362        synchronized (this) {
7363            final int size = mGrantedUriPermissions.size();
7364            for (int i = 0; i < size; i++) {
7365                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7366                for (UriPermission perm : perms.values()) {
7367                    if (perm.persistedModeFlags != 0) {
7368                        persist.add(perm.snapshot());
7369                    }
7370                }
7371            }
7372        }
7373
7374        FileOutputStream fos = null;
7375        try {
7376            fos = mGrantFile.startWrite();
7377
7378            XmlSerializer out = new FastXmlSerializer();
7379            out.setOutput(fos, "utf-8");
7380            out.startDocument(null, true);
7381            out.startTag(null, TAG_URI_GRANTS);
7382            for (UriPermission.Snapshot perm : persist) {
7383                out.startTag(null, TAG_URI_GRANT);
7384                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7385                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7386                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7387                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7388                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7389                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7390                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7391                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7392                out.endTag(null, TAG_URI_GRANT);
7393            }
7394            out.endTag(null, TAG_URI_GRANTS);
7395            out.endDocument();
7396
7397            mGrantFile.finishWrite(fos);
7398        } catch (IOException e) {
7399            if (fos != null) {
7400                mGrantFile.failWrite(fos);
7401            }
7402        }
7403    }
7404
7405    private void readGrantedUriPermissionsLocked() {
7406        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7407
7408        final long now = System.currentTimeMillis();
7409
7410        FileInputStream fis = null;
7411        try {
7412            fis = mGrantFile.openRead();
7413            final XmlPullParser in = Xml.newPullParser();
7414            in.setInput(fis, null);
7415
7416            int type;
7417            while ((type = in.next()) != END_DOCUMENT) {
7418                final String tag = in.getName();
7419                if (type == START_TAG) {
7420                    if (TAG_URI_GRANT.equals(tag)) {
7421                        final int sourceUserId;
7422                        final int targetUserId;
7423                        final int userHandle = readIntAttribute(in,
7424                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7425                        if (userHandle != UserHandle.USER_NULL) {
7426                            // For backwards compatibility.
7427                            sourceUserId = userHandle;
7428                            targetUserId = userHandle;
7429                        } else {
7430                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7431                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7432                        }
7433                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7434                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7435                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7436                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7437                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7438                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7439
7440                        // Sanity check that provider still belongs to source package
7441                        final ProviderInfo pi = getProviderInfoLocked(
7442                                uri.getAuthority(), sourceUserId);
7443                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7444                            int targetUid = -1;
7445                            try {
7446                                targetUid = AppGlobals.getPackageManager()
7447                                        .getPackageUid(targetPkg, targetUserId);
7448                            } catch (RemoteException e) {
7449                            }
7450                            if (targetUid != -1) {
7451                                final UriPermission perm = findOrCreateUriPermissionLocked(
7452                                        sourcePkg, targetPkg, targetUid,
7453                                        new GrantUri(sourceUserId, uri, prefix));
7454                                perm.initPersistedModes(modeFlags, createdTime);
7455                            }
7456                        } else {
7457                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7458                                    + " but instead found " + pi);
7459                        }
7460                    }
7461                }
7462            }
7463        } catch (FileNotFoundException e) {
7464            // Missing grants is okay
7465        } catch (IOException e) {
7466            Slog.wtf(TAG, "Failed reading Uri grants", e);
7467        } catch (XmlPullParserException e) {
7468            Slog.wtf(TAG, "Failed reading Uri grants", e);
7469        } finally {
7470            IoUtils.closeQuietly(fis);
7471        }
7472    }
7473
7474    /**
7475     * @param uri This uri must NOT contain an embedded userId.
7476     * @param userId The userId in which the uri is to be resolved.
7477     */
7478    @Override
7479    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7480        enforceNotIsolatedCaller("takePersistableUriPermission");
7481
7482        Preconditions.checkFlagsArgument(modeFlags,
7483                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7484
7485        synchronized (this) {
7486            final int callingUid = Binder.getCallingUid();
7487            boolean persistChanged = false;
7488            GrantUri grantUri = new GrantUri(userId, uri, false);
7489
7490            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7491                    new GrantUri(userId, uri, false));
7492            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7493                    new GrantUri(userId, uri, true));
7494
7495            final boolean exactValid = (exactPerm != null)
7496                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7497            final boolean prefixValid = (prefixPerm != null)
7498                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7499
7500            if (!(exactValid || prefixValid)) {
7501                throw new SecurityException("No persistable permission grants found for UID "
7502                        + callingUid + " and Uri " + grantUri.toSafeString());
7503            }
7504
7505            if (exactValid) {
7506                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7507            }
7508            if (prefixValid) {
7509                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7510            }
7511
7512            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7513
7514            if (persistChanged) {
7515                schedulePersistUriGrants();
7516            }
7517        }
7518    }
7519
7520    /**
7521     * @param uri This uri must NOT contain an embedded userId.
7522     * @param userId The userId in which the uri is to be resolved.
7523     */
7524    @Override
7525    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7526        enforceNotIsolatedCaller("releasePersistableUriPermission");
7527
7528        Preconditions.checkFlagsArgument(modeFlags,
7529                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7530
7531        synchronized (this) {
7532            final int callingUid = Binder.getCallingUid();
7533            boolean persistChanged = false;
7534
7535            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7536                    new GrantUri(userId, uri, false));
7537            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7538                    new GrantUri(userId, uri, true));
7539            if (exactPerm == null && prefixPerm == null) {
7540                throw new SecurityException("No permission grants found for UID " + callingUid
7541                        + " and Uri " + uri.toSafeString());
7542            }
7543
7544            if (exactPerm != null) {
7545                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7546                removeUriPermissionIfNeededLocked(exactPerm);
7547            }
7548            if (prefixPerm != null) {
7549                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7550                removeUriPermissionIfNeededLocked(prefixPerm);
7551            }
7552
7553            if (persistChanged) {
7554                schedulePersistUriGrants();
7555            }
7556        }
7557    }
7558
7559    /**
7560     * Prune any older {@link UriPermission} for the given UID until outstanding
7561     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7562     *
7563     * @return if any mutations occured that require persisting.
7564     */
7565    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7566        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7567        if (perms == null) return false;
7568        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7569
7570        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7571        for (UriPermission perm : perms.values()) {
7572            if (perm.persistedModeFlags != 0) {
7573                persisted.add(perm);
7574            }
7575        }
7576
7577        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7578        if (trimCount <= 0) return false;
7579
7580        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7581        for (int i = 0; i < trimCount; i++) {
7582            final UriPermission perm = persisted.get(i);
7583
7584            if (DEBUG_URI_PERMISSION) {
7585                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7586            }
7587
7588            perm.releasePersistableModes(~0);
7589            removeUriPermissionIfNeededLocked(perm);
7590        }
7591
7592        return true;
7593    }
7594
7595    @Override
7596    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7597            String packageName, boolean incoming) {
7598        enforceNotIsolatedCaller("getPersistedUriPermissions");
7599        Preconditions.checkNotNull(packageName, "packageName");
7600
7601        final int callingUid = Binder.getCallingUid();
7602        final IPackageManager pm = AppGlobals.getPackageManager();
7603        try {
7604            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7605            if (packageUid != callingUid) {
7606                throw new SecurityException(
7607                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7608            }
7609        } catch (RemoteException e) {
7610            throw new SecurityException("Failed to verify package name ownership");
7611        }
7612
7613        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7614        synchronized (this) {
7615            if (incoming) {
7616                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7617                        callingUid);
7618                if (perms == null) {
7619                    Slog.w(TAG, "No permission grants found for " + packageName);
7620                } else {
7621                    for (UriPermission perm : perms.values()) {
7622                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7623                            result.add(perm.buildPersistedPublicApiObject());
7624                        }
7625                    }
7626                }
7627            } else {
7628                final int size = mGrantedUriPermissions.size();
7629                for (int i = 0; i < size; i++) {
7630                    final ArrayMap<GrantUri, UriPermission> perms =
7631                            mGrantedUriPermissions.valueAt(i);
7632                    for (UriPermission perm : perms.values()) {
7633                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7634                            result.add(perm.buildPersistedPublicApiObject());
7635                        }
7636                    }
7637                }
7638            }
7639        }
7640        return new ParceledListSlice<android.content.UriPermission>(result);
7641    }
7642
7643    @Override
7644    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7645        synchronized (this) {
7646            ProcessRecord app =
7647                who != null ? getRecordForAppLocked(who) : null;
7648            if (app == null) return;
7649
7650            Message msg = Message.obtain();
7651            msg.what = WAIT_FOR_DEBUGGER_MSG;
7652            msg.obj = app;
7653            msg.arg1 = waiting ? 1 : 0;
7654            mHandler.sendMessage(msg);
7655        }
7656    }
7657
7658    @Override
7659    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7660        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7661        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7662        outInfo.availMem = Process.getFreeMemory();
7663        outInfo.totalMem = Process.getTotalMemory();
7664        outInfo.threshold = homeAppMem;
7665        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7666        outInfo.hiddenAppThreshold = cachedAppMem;
7667        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7668                ProcessList.SERVICE_ADJ);
7669        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7670                ProcessList.VISIBLE_APP_ADJ);
7671        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7672                ProcessList.FOREGROUND_APP_ADJ);
7673    }
7674
7675    // =========================================================
7676    // TASK MANAGEMENT
7677    // =========================================================
7678
7679    @Override
7680    public List<IAppTask> getAppTasks(String callingPackage) {
7681        int callingUid = Binder.getCallingUid();
7682        long ident = Binder.clearCallingIdentity();
7683
7684        synchronized(this) {
7685            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7686            try {
7687                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
7688
7689                final int N = mRecentTasks.size();
7690                for (int i = 0; i < N; i++) {
7691                    TaskRecord tr = mRecentTasks.get(i);
7692                    // Skip tasks that do not match the caller.  We don't need to verify
7693                    // callingPackage, because we are also limiting to callingUid and know
7694                    // that will limit to the correct security sandbox.
7695                    if (tr.effectiveUid != callingUid) {
7696                        continue;
7697                    }
7698                    Intent intent = tr.getBaseIntent();
7699                    if (intent == null ||
7700                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7701                        continue;
7702                    }
7703                    ActivityManager.RecentTaskInfo taskInfo =
7704                            createRecentTaskInfoFromTaskRecord(tr);
7705                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7706                    list.add(taskImpl);
7707                }
7708            } finally {
7709                Binder.restoreCallingIdentity(ident);
7710            }
7711            return list;
7712        }
7713    }
7714
7715    @Override
7716    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7717        final int callingUid = Binder.getCallingUid();
7718        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7719
7720        synchronized(this) {
7721            if (DEBUG_ALL) Slog.v(
7722                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7723
7724            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7725                    callingUid);
7726
7727            // TODO: Improve with MRU list from all ActivityStacks.
7728            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7729        }
7730
7731        return list;
7732    }
7733
7734    /**
7735     * Creates a new RecentTaskInfo from a TaskRecord.
7736     */
7737    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7738        // Update the task description to reflect any changes in the task stack
7739        tr.updateTaskDescription();
7740
7741        // Compose the recent task info
7742        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7743        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7744        rti.persistentId = tr.taskId;
7745        rti.baseIntent = new Intent(tr.getBaseIntent());
7746        rti.origActivity = tr.origActivity;
7747        rti.description = tr.lastDescription;
7748        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7749        rti.userId = tr.userId;
7750        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7751        rti.firstActiveTime = tr.firstActiveTime;
7752        rti.lastActiveTime = tr.lastActiveTime;
7753        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7754        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7755        return rti;
7756    }
7757
7758    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7759        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7760                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7761        if (!allowed) {
7762            if (checkPermission(android.Manifest.permission.GET_TASKS,
7763                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7764                // Temporary compatibility: some existing apps on the system image may
7765                // still be requesting the old permission and not switched to the new
7766                // one; if so, we'll still allow them full access.  This means we need
7767                // to see if they are holding the old permission and are a system app.
7768                try {
7769                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7770                        allowed = true;
7771                        Slog.w(TAG, caller + ": caller " + callingUid
7772                                + " is using old GET_TASKS but privileged; allowing");
7773                    }
7774                } catch (RemoteException e) {
7775                }
7776            }
7777        }
7778        if (!allowed) {
7779            Slog.w(TAG, caller + ": caller " + callingUid
7780                    + " does not hold GET_TASKS; limiting output");
7781        }
7782        return allowed;
7783    }
7784
7785    @Override
7786    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7787        final int callingUid = Binder.getCallingUid();
7788        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7789                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7790
7791        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7792        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7793        synchronized (this) {
7794            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7795                    callingUid);
7796            final boolean detailed = checkCallingPermission(
7797                    android.Manifest.permission.GET_DETAILED_TASKS)
7798                    == PackageManager.PERMISSION_GRANTED;
7799
7800            final int N = mRecentTasks.size();
7801            ArrayList<ActivityManager.RecentTaskInfo> res
7802                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7803                            maxNum < N ? maxNum : N);
7804
7805            final Set<Integer> includedUsers;
7806            if (includeProfiles) {
7807                includedUsers = getProfileIdsLocked(userId);
7808            } else {
7809                includedUsers = new HashSet<Integer>();
7810            }
7811            includedUsers.add(Integer.valueOf(userId));
7812
7813            for (int i=0; i<N && maxNum > 0; i++) {
7814                TaskRecord tr = mRecentTasks.get(i);
7815                // Only add calling user or related users recent tasks
7816                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7817                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7818                    continue;
7819                }
7820
7821                // Return the entry if desired by the caller.  We always return
7822                // the first entry, because callers always expect this to be the
7823                // foreground app.  We may filter others if the caller has
7824                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7825                // we should exclude the entry.
7826
7827                if (i == 0
7828                        || withExcluded
7829                        || (tr.intent == null)
7830                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7831                                == 0)) {
7832                    if (!allowed) {
7833                        // If the caller doesn't have the GET_TASKS permission, then only
7834                        // allow them to see a small subset of tasks -- their own and home.
7835                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7836                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7837                            continue;
7838                        }
7839                    }
7840                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7841                        if (tr.stack != null && tr.stack.isHomeStack()) {
7842                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7843                            continue;
7844                        }
7845                    }
7846                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7847                        // Don't include auto remove tasks that are finished or finishing.
7848                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7849                                + tr);
7850                        continue;
7851                    }
7852                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7853                            && !tr.isAvailable) {
7854                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7855                        continue;
7856                    }
7857
7858                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7859                    if (!detailed) {
7860                        rti.baseIntent.replaceExtras((Bundle)null);
7861                    }
7862
7863                    res.add(rti);
7864                    maxNum--;
7865                }
7866            }
7867            return res;
7868        }
7869    }
7870
7871    @Override
7872    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7873        synchronized (this) {
7874            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7875                    "getTaskThumbnail()");
7876            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
7877            if (tr != null) {
7878                return tr.getTaskThumbnailLocked();
7879            }
7880        }
7881        return null;
7882    }
7883
7884    @Override
7885    public int addAppTask(IBinder activityToken, Intent intent,
7886            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7887        final int callingUid = Binder.getCallingUid();
7888        final long callingIdent = Binder.clearCallingIdentity();
7889
7890        try {
7891            synchronized (this) {
7892                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7893                if (r == null) {
7894                    throw new IllegalArgumentException("Activity does not exist; token="
7895                            + activityToken);
7896                }
7897                ComponentName comp = intent.getComponent();
7898                if (comp == null) {
7899                    throw new IllegalArgumentException("Intent " + intent
7900                            + " must specify explicit component");
7901                }
7902                if (thumbnail.getWidth() != mThumbnailWidth
7903                        || thumbnail.getHeight() != mThumbnailHeight) {
7904                    throw new IllegalArgumentException("Bad thumbnail size: got "
7905                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7906                            + mThumbnailWidth + "x" + mThumbnailHeight);
7907                }
7908                if (intent.getSelector() != null) {
7909                    intent.setSelector(null);
7910                }
7911                if (intent.getSourceBounds() != null) {
7912                    intent.setSourceBounds(null);
7913                }
7914                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7915                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7916                        // The caller has added this as an auto-remove task...  that makes no
7917                        // sense, so turn off auto-remove.
7918                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7919                    }
7920                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7921                    // Must be a new task.
7922                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7923                }
7924                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7925                    mLastAddedTaskActivity = null;
7926                }
7927                ActivityInfo ainfo = mLastAddedTaskActivity;
7928                if (ainfo == null) {
7929                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7930                            comp, 0, UserHandle.getUserId(callingUid));
7931                    if (ainfo.applicationInfo.uid != callingUid) {
7932                        throw new SecurityException(
7933                                "Can't add task for another application: target uid="
7934                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7935                    }
7936                }
7937
7938                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7939                        intent, description);
7940
7941                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7942                if (trimIdx >= 0) {
7943                    // If this would have caused a trim, then we'll abort because that
7944                    // means it would be added at the end of the list but then just removed.
7945                    return INVALID_TASK_ID;
7946                }
7947
7948                final int N = mRecentTasks.size();
7949                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7950                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7951                    tr.removedFromRecents();
7952                }
7953
7954                task.inRecents = true;
7955                mRecentTasks.add(task);
7956                r.task.stack.addTask(task, false, false);
7957
7958                task.setLastThumbnail(thumbnail);
7959                task.freeLastThumbnail();
7960
7961                return task.taskId;
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(callingIdent);
7965        }
7966    }
7967
7968    @Override
7969    public Point getAppTaskThumbnailSize() {
7970        synchronized (this) {
7971            return new Point(mThumbnailWidth,  mThumbnailHeight);
7972        }
7973    }
7974
7975    @Override
7976    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7977        synchronized (this) {
7978            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7979            if (r != null) {
7980                r.setTaskDescription(td);
7981                r.task.updateTaskDescription();
7982            }
7983        }
7984    }
7985
7986    @Override
7987    public void setTaskResizeable(int taskId, boolean resizeable) {
7988        synchronized (this) {
7989            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7990            if (task == null) {
7991                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
7992                return;
7993            }
7994            if (task.mResizeable != resizeable) {
7995                task.mResizeable = resizeable;
7996                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
7997                mStackSupervisor.resumeTopActivitiesLocked();
7998            }
7999        }
8000    }
8001
8002    @Override
8003    public void resizeTask(int taskId, Rect bounds) {
8004        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8005                "resizeTask()");
8006        long ident = Binder.clearCallingIdentity();
8007        try {
8008            synchronized (this) {
8009                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8010                if (task == null) {
8011                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8012                    return;
8013                }
8014                mStackSupervisor.resizeTaskLocked(task, bounds);
8015            }
8016        } finally {
8017            Binder.restoreCallingIdentity(ident);
8018        }
8019    }
8020
8021    @Override
8022    public Bitmap getTaskDescriptionIcon(String filename) {
8023        if (!FileUtils.isValidExtFilename(filename)
8024                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8025            throw new IllegalArgumentException("Bad filename: " + filename);
8026        }
8027        return mTaskPersister.getTaskDescriptionIcon(filename);
8028    }
8029
8030    @Override
8031    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8032            throws RemoteException {
8033        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8034                opts.getCustomInPlaceResId() == 0) {
8035            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8036                    "with valid animation");
8037        }
8038        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8039        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8040                opts.getCustomInPlaceResId());
8041        mWindowManager.executeAppTransition();
8042    }
8043
8044    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8045        mRecentTasks.remove(tr);
8046        tr.removedFromRecents();
8047        ComponentName component = tr.getBaseIntent().getComponent();
8048        if (component == null) {
8049            Slog.w(TAG, "No component for base intent of task: " + tr);
8050            return;
8051        }
8052
8053        if (!killProcess) {
8054            return;
8055        }
8056
8057        // Determine if the process(es) for this task should be killed.
8058        final String pkg = component.getPackageName();
8059        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8060        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8061        for (int i = 0; i < pmap.size(); i++) {
8062
8063            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8064            for (int j = 0; j < uids.size(); j++) {
8065                ProcessRecord proc = uids.valueAt(j);
8066                if (proc.userId != tr.userId) {
8067                    // Don't kill process for a different user.
8068                    continue;
8069                }
8070                if (proc == mHomeProcess) {
8071                    // Don't kill the home process along with tasks from the same package.
8072                    continue;
8073                }
8074                if (!proc.pkgList.containsKey(pkg)) {
8075                    // Don't kill process that is not associated with this task.
8076                    continue;
8077                }
8078
8079                for (int k = 0; k < proc.activities.size(); k++) {
8080                    TaskRecord otherTask = proc.activities.get(k).task;
8081                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8082                        // Don't kill process(es) that has an activity in a different task that is
8083                        // also in recents.
8084                        return;
8085                    }
8086                }
8087
8088                // Add process to kill list.
8089                procsToKill.add(proc);
8090            }
8091        }
8092
8093        // Find any running services associated with this app and stop if needed.
8094        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8095
8096        // Kill the running processes.
8097        for (int i = 0; i < procsToKill.size(); i++) {
8098            ProcessRecord pr = procsToKill.get(i);
8099            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8100                pr.kill("remove task", true);
8101            } else {
8102                pr.waitingToKill = "remove task";
8103            }
8104        }
8105    }
8106
8107    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8108        // Remove all tasks with activities in the specified package from the list of recent tasks
8109        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8110            TaskRecord tr = mRecentTasks.get(i);
8111            if (tr.userId != userId) continue;
8112
8113            ComponentName cn = tr.intent.getComponent();
8114            if (cn != null && cn.getPackageName().equals(packageName)) {
8115                // If the package name matches, remove the task.
8116                removeTaskByIdLocked(tr.taskId, true);
8117            }
8118        }
8119    }
8120
8121    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8122        final IPackageManager pm = AppGlobals.getPackageManager();
8123        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8124
8125        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8126            TaskRecord tr = mRecentTasks.get(i);
8127            if (tr.userId != userId) continue;
8128
8129            ComponentName cn = tr.intent.getComponent();
8130            if (cn != null && cn.getPackageName().equals(packageName)) {
8131                // Skip if component still exists in the package.
8132                if (componentsKnownToExist.contains(cn)) continue;
8133
8134                try {
8135                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8136                    if (info != null) {
8137                        componentsKnownToExist.add(cn);
8138                    } else {
8139                        removeTaskByIdLocked(tr.taskId, false);
8140                    }
8141                } catch (RemoteException e) {
8142                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8143                }
8144            }
8145        }
8146    }
8147
8148    /**
8149     * Removes the task with the specified task id.
8150     *
8151     * @param taskId Identifier of the task to be removed.
8152     * @param killProcess Kill any process associated with the task if possible.
8153     * @return Returns true if the given task was found and removed.
8154     */
8155    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8156        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8157        if (tr != null) {
8158            tr.removeTaskActivitiesLocked();
8159            cleanUpRemovedTaskLocked(tr, killProcess);
8160            if (tr.isPersistable) {
8161                notifyTaskPersisterLocked(null, true);
8162            }
8163            return true;
8164        }
8165        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8166        return false;
8167    }
8168
8169    @Override
8170    public boolean removeTask(int taskId) {
8171        synchronized (this) {
8172            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8173                    "removeTask()");
8174            long ident = Binder.clearCallingIdentity();
8175            try {
8176                return removeTaskByIdLocked(taskId, true);
8177            } finally {
8178                Binder.restoreCallingIdentity(ident);
8179            }
8180        }
8181    }
8182
8183    /**
8184     * TODO: Add mController hook
8185     */
8186    @Override
8187    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8188        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8189                "moveTaskToFront()");
8190
8191        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8192        synchronized(this) {
8193            moveTaskToFrontLocked(taskId, flags, options);
8194        }
8195    }
8196
8197    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8198        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8199                Binder.getCallingUid(), -1, -1, "Task to front")) {
8200            ActivityOptions.abort(options);
8201            return;
8202        }
8203        final long origId = Binder.clearCallingIdentity();
8204        try {
8205            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8206            if (task == null) {
8207                Slog.d(TAG, "Could not find task for id: "+ taskId);
8208                return;
8209            }
8210            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8211                mStackSupervisor.showLockTaskToast();
8212                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8213                return;
8214            }
8215            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8216            if (prev != null && prev.isRecentsActivity()) {
8217                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8218            }
8219            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8220        } finally {
8221            Binder.restoreCallingIdentity(origId);
8222        }
8223        ActivityOptions.abort(options);
8224    }
8225
8226    /**
8227     * Moves an activity, and all of the other activities within the same task, to the bottom
8228     * of the history stack.  The activity's order within the task is unchanged.
8229     *
8230     * @param token A reference to the activity we wish to move
8231     * @param nonRoot If false then this only works if the activity is the root
8232     *                of a task; if true it will work for any activity in a task.
8233     * @return Returns true if the move completed, false if not.
8234     */
8235    @Override
8236    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8237        enforceNotIsolatedCaller("moveActivityTaskToBack");
8238        synchronized(this) {
8239            final long origId = Binder.clearCallingIdentity();
8240            try {
8241                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8242                if (taskId >= 0) {
8243                    if ((mStackSupervisor.mLockTaskModeTask != null)
8244                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8245                        mStackSupervisor.showLockTaskToast();
8246                        return false;
8247                    }
8248                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8249                }
8250            } finally {
8251                Binder.restoreCallingIdentity(origId);
8252            }
8253        }
8254        return false;
8255    }
8256
8257    @Override
8258    public void moveTaskBackwards(int task) {
8259        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8260                "moveTaskBackwards()");
8261
8262        synchronized(this) {
8263            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8264                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8265                return;
8266            }
8267            final long origId = Binder.clearCallingIdentity();
8268            moveTaskBackwardsLocked(task);
8269            Binder.restoreCallingIdentity(origId);
8270        }
8271    }
8272
8273    private final void moveTaskBackwardsLocked(int task) {
8274        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8275    }
8276
8277    @Override
8278    public IBinder getHomeActivityToken() throws RemoteException {
8279        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8280                "getHomeActivityToken()");
8281        synchronized (this) {
8282            return mStackSupervisor.getHomeActivityToken();
8283        }
8284    }
8285
8286    @Override
8287    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8288            IActivityContainerCallback callback) throws RemoteException {
8289        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8290                "createActivityContainer()");
8291        synchronized (this) {
8292            if (parentActivityToken == null) {
8293                throw new IllegalArgumentException("parent token must not be null");
8294            }
8295            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8296            if (r == null) {
8297                return null;
8298            }
8299            if (callback == null) {
8300                throw new IllegalArgumentException("callback must not be null");
8301            }
8302            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8303        }
8304    }
8305
8306    @Override
8307    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8308        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8309                "deleteActivityContainer()");
8310        synchronized (this) {
8311            mStackSupervisor.deleteActivityContainer(container);
8312        }
8313    }
8314
8315    @Override
8316    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8317        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8318                "createStackOnDisplay()");
8319        synchronized (this) {
8320            final int stackId = mStackSupervisor.getNextStackId();
8321            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8322            if (stack == null) {
8323                return null;
8324            }
8325            return stack.mActivityContainer;
8326        }
8327    }
8328
8329    @Override
8330    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8331        synchronized (this) {
8332            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8333            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8334                return stack.mActivityContainer.getDisplayId();
8335            }
8336            return Display.DEFAULT_DISPLAY;
8337        }
8338    }
8339
8340    @Override
8341    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8342        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8343                "moveTaskToStack()");
8344        if (stackId == HOME_STACK_ID) {
8345            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8346                    new RuntimeException("here").fillInStackTrace());
8347        }
8348        synchronized (this) {
8349            long ident = Binder.clearCallingIdentity();
8350            try {
8351                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8352                        + stackId + " toTop=" + toTop);
8353                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8354            } finally {
8355                Binder.restoreCallingIdentity(ident);
8356            }
8357        }
8358    }
8359
8360    @Override
8361    public void resizeStack(int stackId, Rect bounds) {
8362        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8363                "resizeStack()");
8364        long ident = Binder.clearCallingIdentity();
8365        try {
8366            synchronized (this) {
8367                mStackSupervisor.resizeStackLocked(stackId, bounds);
8368            }
8369        } finally {
8370            Binder.restoreCallingIdentity(ident);
8371        }
8372    }
8373
8374    @Override
8375    public List<StackInfo> getAllStackInfos() {
8376        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8377                "getAllStackInfos()");
8378        long ident = Binder.clearCallingIdentity();
8379        try {
8380            synchronized (this) {
8381                return mStackSupervisor.getAllStackInfosLocked();
8382            }
8383        } finally {
8384            Binder.restoreCallingIdentity(ident);
8385        }
8386    }
8387
8388    @Override
8389    public StackInfo getStackInfo(int stackId) {
8390        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8391                "getStackInfo()");
8392        long ident = Binder.clearCallingIdentity();
8393        try {
8394            synchronized (this) {
8395                return mStackSupervisor.getStackInfoLocked(stackId);
8396            }
8397        } finally {
8398            Binder.restoreCallingIdentity(ident);
8399        }
8400    }
8401
8402    @Override
8403    public boolean isInHomeStack(int taskId) {
8404        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8405                "getStackInfo()");
8406        long ident = Binder.clearCallingIdentity();
8407        try {
8408            synchronized (this) {
8409                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8410                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8411            }
8412        } finally {
8413            Binder.restoreCallingIdentity(ident);
8414        }
8415    }
8416
8417    @Override
8418    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8419        synchronized(this) {
8420            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8421        }
8422    }
8423
8424    private boolean isLockTaskAuthorized(String pkg) {
8425        final DevicePolicyManager dpm = (DevicePolicyManager)
8426                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8427        try {
8428            int uid = mContext.getPackageManager().getPackageUid(pkg,
8429                    Binder.getCallingUserHandle().getIdentifier());
8430            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8431        } catch (NameNotFoundException e) {
8432            return false;
8433        }
8434    }
8435
8436    void startLockTaskMode(TaskRecord task) {
8437        final String pkg;
8438        synchronized (this) {
8439            pkg = task.intent.getComponent().getPackageName();
8440        }
8441        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8442        // is initiated by system after the pinning request was shown and locked mode is initiated
8443        // by an authorized app directly
8444        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8445        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8446            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8447                    StatusBarManagerInternal.class);
8448            if (statusBarManager != null) {
8449                statusBarManager.showScreenPinningRequest();
8450            }
8451            return;
8452        }
8453        long ident = Binder.clearCallingIdentity();
8454        try {
8455            synchronized (this) {
8456                // Since we lost lock on task, make sure it is still there.
8457                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8458                if (task != null) {
8459                    if (!isSystemInitiated
8460                            && ((mStackSupervisor.getFocusedStack() == null)
8461                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8462                        throw new IllegalArgumentException("Invalid task, not in foreground");
8463                    }
8464                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8465                            ActivityManager.LOCK_TASK_MODE_PINNED :
8466                            ActivityManager.LOCK_TASK_MODE_LOCKED,
8467                            "startLockTask");
8468                }
8469            }
8470        } finally {
8471            Binder.restoreCallingIdentity(ident);
8472        }
8473    }
8474
8475    @Override
8476    public void startLockTaskMode(int taskId) {
8477        final TaskRecord task;
8478        long ident = Binder.clearCallingIdentity();
8479        try {
8480            synchronized (this) {
8481                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8482            }
8483        } finally {
8484            Binder.restoreCallingIdentity(ident);
8485        }
8486        if (task != null) {
8487            startLockTaskMode(task);
8488        }
8489    }
8490
8491    @Override
8492    public void startLockTaskMode(IBinder token) {
8493        final TaskRecord task;
8494        long ident = Binder.clearCallingIdentity();
8495        try {
8496            synchronized (this) {
8497                final ActivityRecord r = ActivityRecord.forToken(token);
8498                if (r == null) {
8499                    return;
8500                }
8501                task = r.task;
8502            }
8503        } finally {
8504            Binder.restoreCallingIdentity(ident);
8505        }
8506        if (task != null) {
8507            startLockTaskMode(task);
8508        }
8509    }
8510
8511    @Override
8512    public void startLockTaskModeOnCurrent() throws RemoteException {
8513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8514                "startLockTaskModeOnCurrent");
8515        long ident = Binder.clearCallingIdentity();
8516        try {
8517            ActivityRecord r = null;
8518            synchronized (this) {
8519                r = mStackSupervisor.topRunningActivityLocked();
8520            }
8521            startLockTaskMode(r.task);
8522        } finally {
8523            Binder.restoreCallingIdentity(ident);
8524        }
8525    }
8526
8527    @Override
8528    public void stopLockTaskMode() {
8529        // Verify that the user matches the package of the intent for the TaskRecord
8530        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8531        // and stopLockTaskMode.
8532        final int callingUid = Binder.getCallingUid();
8533        if (callingUid != Process.SYSTEM_UID) {
8534            try {
8535                String pkg =
8536                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8537                int uid = mContext.getPackageManager().getPackageUid(pkg,
8538                        Binder.getCallingUserHandle().getIdentifier());
8539                if (uid != callingUid) {
8540                    throw new SecurityException("Invalid uid, expected " + uid);
8541                }
8542            } catch (NameNotFoundException e) {
8543                Log.d(TAG, "stopLockTaskMode " + e);
8544                return;
8545            }
8546        }
8547        long ident = Binder.clearCallingIdentity();
8548        try {
8549            Log.d(TAG, "stopLockTaskMode");
8550            // Stop lock task
8551            synchronized (this) {
8552                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
8553                        "stopLockTask");
8554            }
8555        } finally {
8556            Binder.restoreCallingIdentity(ident);
8557        }
8558    }
8559
8560    @Override
8561    public void stopLockTaskModeOnCurrent() throws RemoteException {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "stopLockTaskModeOnCurrent");
8564        long ident = Binder.clearCallingIdentity();
8565        try {
8566            stopLockTaskMode();
8567        } finally {
8568            Binder.restoreCallingIdentity(ident);
8569        }
8570    }
8571
8572    @Override
8573    public boolean isInLockTaskMode() {
8574        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
8575    }
8576
8577    @Override
8578    public int getLockTaskModeState() {
8579        synchronized (this) {
8580            return mStackSupervisor.getLockTaskModeState();
8581        }
8582    }
8583
8584    // =========================================================
8585    // CONTENT PROVIDERS
8586    // =========================================================
8587
8588    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8589        List<ProviderInfo> providers = null;
8590        try {
8591            providers = AppGlobals.getPackageManager().
8592                queryContentProviders(app.processName, app.uid,
8593                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8594        } catch (RemoteException ex) {
8595        }
8596        if (DEBUG_MU)
8597            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8598        int userId = app.userId;
8599        if (providers != null) {
8600            int N = providers.size();
8601            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8602            for (int i=0; i<N; i++) {
8603                ProviderInfo cpi =
8604                    (ProviderInfo)providers.get(i);
8605                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8606                        cpi.name, cpi.flags);
8607                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8608                    // This is a singleton provider, but a user besides the
8609                    // default user is asking to initialize a process it runs
8610                    // in...  well, no, it doesn't actually run in this process,
8611                    // it runs in the process of the default user.  Get rid of it.
8612                    providers.remove(i);
8613                    N--;
8614                    i--;
8615                    continue;
8616                }
8617
8618                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8619                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8620                if (cpr == null) {
8621                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8622                    mProviderMap.putProviderByClass(comp, cpr);
8623                }
8624                if (DEBUG_MU)
8625                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8626                app.pubProviders.put(cpi.name, cpr);
8627                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8628                    // Don't add this if it is a platform component that is marked
8629                    // to run in multiple processes, because this is actually
8630                    // part of the framework so doesn't make sense to track as a
8631                    // separate apk in the process.
8632                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8633                            mProcessStats);
8634                }
8635                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8636            }
8637        }
8638        return providers;
8639    }
8640
8641    /**
8642     * Check if {@link ProcessRecord} has a possible chance at accessing the
8643     * given {@link ProviderInfo}. Final permission checking is always done
8644     * in {@link ContentProvider}.
8645     */
8646    private final String checkContentProviderPermissionLocked(
8647            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8648        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8649        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8650        boolean checkedGrants = false;
8651        if (checkUser) {
8652            // Looking for cross-user grants before enforcing the typical cross-users permissions
8653            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8654            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8655                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8656                    return null;
8657                }
8658                checkedGrants = true;
8659            }
8660            userId = handleIncomingUser(callingPid, callingUid, userId,
8661                    false, ALLOW_NON_FULL,
8662                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8663            if (userId != tmpTargetUserId) {
8664                // When we actually went to determine the final targer user ID, this ended
8665                // up different than our initial check for the authority.  This is because
8666                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8667                // SELF.  So we need to re-check the grants again.
8668                checkedGrants = false;
8669            }
8670        }
8671        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8672                cpi.applicationInfo.uid, cpi.exported)
8673                == PackageManager.PERMISSION_GRANTED) {
8674            return null;
8675        }
8676        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8677                cpi.applicationInfo.uid, cpi.exported)
8678                == PackageManager.PERMISSION_GRANTED) {
8679            return null;
8680        }
8681
8682        PathPermission[] pps = cpi.pathPermissions;
8683        if (pps != null) {
8684            int i = pps.length;
8685            while (i > 0) {
8686                i--;
8687                PathPermission pp = pps[i];
8688                String pprperm = pp.getReadPermission();
8689                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8690                        cpi.applicationInfo.uid, cpi.exported)
8691                        == PackageManager.PERMISSION_GRANTED) {
8692                    return null;
8693                }
8694                String ppwperm = pp.getWritePermission();
8695                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8696                        cpi.applicationInfo.uid, cpi.exported)
8697                        == PackageManager.PERMISSION_GRANTED) {
8698                    return null;
8699                }
8700            }
8701        }
8702        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8703            return null;
8704        }
8705
8706        String msg;
8707        if (!cpi.exported) {
8708            msg = "Permission Denial: opening provider " + cpi.name
8709                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8710                    + ", uid=" + callingUid + ") that is not exported from uid "
8711                    + cpi.applicationInfo.uid;
8712        } else {
8713            msg = "Permission Denial: opening provider " + cpi.name
8714                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8715                    + ", uid=" + callingUid + ") requires "
8716                    + cpi.readPermission + " or " + cpi.writePermission;
8717        }
8718        Slog.w(TAG, msg);
8719        return msg;
8720    }
8721
8722    /**
8723     * Returns if the ContentProvider has granted a uri to callingUid
8724     */
8725    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8726        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8727        if (perms != null) {
8728            for (int i=perms.size()-1; i>=0; i--) {
8729                GrantUri grantUri = perms.keyAt(i);
8730                if (grantUri.sourceUserId == userId || !checkUser) {
8731                    if (matchesProvider(grantUri.uri, cpi)) {
8732                        return true;
8733                    }
8734                }
8735            }
8736        }
8737        return false;
8738    }
8739
8740    /**
8741     * Returns true if the uri authority is one of the authorities specified in the provider.
8742     */
8743    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8744        String uriAuth = uri.getAuthority();
8745        String cpiAuth = cpi.authority;
8746        if (cpiAuth.indexOf(';') == -1) {
8747            return cpiAuth.equals(uriAuth);
8748        }
8749        String[] cpiAuths = cpiAuth.split(";");
8750        int length = cpiAuths.length;
8751        for (int i = 0; i < length; i++) {
8752            if (cpiAuths[i].equals(uriAuth)) return true;
8753        }
8754        return false;
8755    }
8756
8757    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8758            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8759        if (r != null) {
8760            for (int i=0; i<r.conProviders.size(); i++) {
8761                ContentProviderConnection conn = r.conProviders.get(i);
8762                if (conn.provider == cpr) {
8763                    if (DEBUG_PROVIDER) Slog.v(TAG,
8764                            "Adding provider requested by "
8765                            + r.processName + " from process "
8766                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8767                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8768                    if (stable) {
8769                        conn.stableCount++;
8770                        conn.numStableIncs++;
8771                    } else {
8772                        conn.unstableCount++;
8773                        conn.numUnstableIncs++;
8774                    }
8775                    return conn;
8776                }
8777            }
8778            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8779            if (stable) {
8780                conn.stableCount = 1;
8781                conn.numStableIncs = 1;
8782            } else {
8783                conn.unstableCount = 1;
8784                conn.numUnstableIncs = 1;
8785            }
8786            cpr.connections.add(conn);
8787            r.conProviders.add(conn);
8788            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8789            return conn;
8790        }
8791        cpr.addExternalProcessHandleLocked(externalProcessToken);
8792        return null;
8793    }
8794
8795    boolean decProviderCountLocked(ContentProviderConnection conn,
8796            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8797        if (conn != null) {
8798            cpr = conn.provider;
8799            if (DEBUG_PROVIDER) Slog.v(TAG,
8800                    "Removing provider requested by "
8801                    + conn.client.processName + " from process "
8802                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8803                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8804            if (stable) {
8805                conn.stableCount--;
8806            } else {
8807                conn.unstableCount--;
8808            }
8809            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8810                cpr.connections.remove(conn);
8811                conn.client.conProviders.remove(conn);
8812                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8813                return true;
8814            }
8815            return false;
8816        }
8817        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8818        return false;
8819    }
8820
8821    private void checkTime(long startTime, String where) {
8822        long now = SystemClock.elapsedRealtime();
8823        if ((now-startTime) > 1000) {
8824            // If we are taking more than a second, log about it.
8825            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8826        }
8827    }
8828
8829    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8830            String name, IBinder token, boolean stable, int userId) {
8831        ContentProviderRecord cpr;
8832        ContentProviderConnection conn = null;
8833        ProviderInfo cpi = null;
8834
8835        synchronized(this) {
8836            long startTime = SystemClock.elapsedRealtime();
8837
8838            ProcessRecord r = null;
8839            if (caller != null) {
8840                r = getRecordForAppLocked(caller);
8841                if (r == null) {
8842                    throw new SecurityException(
8843                            "Unable to find app for caller " + caller
8844                          + " (pid=" + Binder.getCallingPid()
8845                          + ") when getting content provider " + name);
8846                }
8847            }
8848
8849            boolean checkCrossUser = true;
8850
8851            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8852
8853            // First check if this content provider has been published...
8854            cpr = mProviderMap.getProviderByName(name, userId);
8855            // If that didn't work, check if it exists for user 0 and then
8856            // verify that it's a singleton provider before using it.
8857            if (cpr == null && userId != UserHandle.USER_OWNER) {
8858                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8859                if (cpr != null) {
8860                    cpi = cpr.info;
8861                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8862                            cpi.name, cpi.flags)
8863                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8864                        userId = UserHandle.USER_OWNER;
8865                        checkCrossUser = false;
8866                    } else {
8867                        cpr = null;
8868                        cpi = null;
8869                    }
8870                }
8871            }
8872
8873            boolean providerRunning = cpr != null;
8874            if (providerRunning) {
8875                cpi = cpr.info;
8876                String msg;
8877                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8878                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8879                        != null) {
8880                    throw new SecurityException(msg);
8881                }
8882                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8883
8884                if (r != null && cpr.canRunHere(r)) {
8885                    // This provider has been published or is in the process
8886                    // of being published...  but it is also allowed to run
8887                    // in the caller's process, so don't make a connection
8888                    // and just let the caller instantiate its own instance.
8889                    ContentProviderHolder holder = cpr.newHolder(null);
8890                    // don't give caller the provider object, it needs
8891                    // to make its own.
8892                    holder.provider = null;
8893                    return holder;
8894                }
8895
8896                final long origId = Binder.clearCallingIdentity();
8897
8898                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8899
8900                // In this case the provider instance already exists, so we can
8901                // return it right away.
8902                conn = incProviderCountLocked(r, cpr, token, stable);
8903                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8904                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8905                        // If this is a perceptible app accessing the provider,
8906                        // make sure to count it as being accessed and thus
8907                        // back up on the LRU list.  This is good because
8908                        // content providers are often expensive to start.
8909                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8910                        updateLruProcessLocked(cpr.proc, false, null);
8911                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8912                    }
8913                }
8914
8915                if (cpr.proc != null) {
8916                    if (false) {
8917                        if (cpr.name.flattenToShortString().equals(
8918                                "com.android.providers.calendar/.CalendarProvider2")) {
8919                            Slog.v(TAG, "****************** KILLING "
8920                                + cpr.name.flattenToShortString());
8921                            Process.killProcess(cpr.proc.pid);
8922                        }
8923                    }
8924                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8925                    boolean success = updateOomAdjLocked(cpr.proc);
8926                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8927                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8928                    // NOTE: there is still a race here where a signal could be
8929                    // pending on the process even though we managed to update its
8930                    // adj level.  Not sure what to do about this, but at least
8931                    // the race is now smaller.
8932                    if (!success) {
8933                        // Uh oh...  it looks like the provider's process
8934                        // has been killed on us.  We need to wait for a new
8935                        // process to be started, and make sure its death
8936                        // doesn't kill our process.
8937                        Slog.i(TAG,
8938                                "Existing provider " + cpr.name.flattenToShortString()
8939                                + " is crashing; detaching " + r);
8940                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8941                        checkTime(startTime, "getContentProviderImpl: before appDied");
8942                        appDiedLocked(cpr.proc);
8943                        checkTime(startTime, "getContentProviderImpl: after appDied");
8944                        if (!lastRef) {
8945                            // This wasn't the last ref our process had on
8946                            // the provider...  we have now been killed, bail.
8947                            return null;
8948                        }
8949                        providerRunning = false;
8950                        conn = null;
8951                    }
8952                }
8953
8954                Binder.restoreCallingIdentity(origId);
8955            }
8956
8957            boolean singleton;
8958            if (!providerRunning) {
8959                try {
8960                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8961                    cpi = AppGlobals.getPackageManager().
8962                        resolveContentProvider(name,
8963                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8964                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8965                } catch (RemoteException ex) {
8966                }
8967                if (cpi == null) {
8968                    return null;
8969                }
8970                // If the provider is a singleton AND
8971                // (it's a call within the same user || the provider is a
8972                // privileged app)
8973                // Then allow connecting to the singleton provider
8974                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8975                        cpi.name, cpi.flags)
8976                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8977                if (singleton) {
8978                    userId = UserHandle.USER_OWNER;
8979                }
8980                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8981                checkTime(startTime, "getContentProviderImpl: got app info for user");
8982
8983                String msg;
8984                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8985                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8986                        != null) {
8987                    throw new SecurityException(msg);
8988                }
8989                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8990
8991                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8992                        && !cpi.processName.equals("system")) {
8993                    // If this content provider does not run in the system
8994                    // process, and the system is not yet ready to run other
8995                    // processes, then fail fast instead of hanging.
8996                    throw new IllegalArgumentException(
8997                            "Attempt to launch content provider before system ready");
8998                }
8999
9000                // Make sure that the user who owns this provider is running.  If not,
9001                // we don't want to allow it to run.
9002                if (!isUserRunningLocked(userId, false)) {
9003                    Slog.w(TAG, "Unable to launch app "
9004                            + cpi.applicationInfo.packageName + "/"
9005                            + cpi.applicationInfo.uid + " for provider "
9006                            + name + ": user " + userId + " is stopped");
9007                    return null;
9008                }
9009
9010                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9011                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9012                cpr = mProviderMap.getProviderByClass(comp, userId);
9013                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9014                final boolean firstClass = cpr == null;
9015                if (firstClass) {
9016                    final long ident = Binder.clearCallingIdentity();
9017                    try {
9018                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9019                        ApplicationInfo ai =
9020                            AppGlobals.getPackageManager().
9021                                getApplicationInfo(
9022                                        cpi.applicationInfo.packageName,
9023                                        STOCK_PM_FLAGS, userId);
9024                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9025                        if (ai == null) {
9026                            Slog.w(TAG, "No package info for content provider "
9027                                    + cpi.name);
9028                            return null;
9029                        }
9030                        ai = getAppInfoForUser(ai, userId);
9031                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9032                    } catch (RemoteException ex) {
9033                        // pm is in same process, this will never happen.
9034                    } finally {
9035                        Binder.restoreCallingIdentity(ident);
9036                    }
9037                }
9038
9039                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9040
9041                if (r != null && cpr.canRunHere(r)) {
9042                    // If this is a multiprocess provider, then just return its
9043                    // info and allow the caller to instantiate it.  Only do
9044                    // this if the provider is the same user as the caller's
9045                    // process, or can run as root (so can be in any process).
9046                    return cpr.newHolder(null);
9047                }
9048
9049                if (DEBUG_PROVIDER) {
9050                    RuntimeException e = new RuntimeException("here");
9051                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9052                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9053                }
9054
9055                // This is single process, and our app is now connecting to it.
9056                // See if we are already in the process of launching this
9057                // provider.
9058                final int N = mLaunchingProviders.size();
9059                int i;
9060                for (i=0; i<N; i++) {
9061                    if (mLaunchingProviders.get(i) == cpr) {
9062                        break;
9063                    }
9064                }
9065
9066                // If the provider is not already being launched, then get it
9067                // started.
9068                if (i >= N) {
9069                    final long origId = Binder.clearCallingIdentity();
9070
9071                    try {
9072                        // Content provider is now in use, its package can't be stopped.
9073                        try {
9074                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9075                            AppGlobals.getPackageManager().setPackageStoppedState(
9076                                    cpr.appInfo.packageName, false, userId);
9077                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9078                        } catch (RemoteException e) {
9079                        } catch (IllegalArgumentException e) {
9080                            Slog.w(TAG, "Failed trying to unstop package "
9081                                    + cpr.appInfo.packageName + ": " + e);
9082                        }
9083
9084                        // Use existing process if already started
9085                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9086                        ProcessRecord proc = getProcessRecordLocked(
9087                                cpi.processName, cpr.appInfo.uid, false);
9088                        if (proc != null && proc.thread != null) {
9089                            if (DEBUG_PROVIDER) {
9090                                Slog.d(TAG, "Installing in existing process " + proc);
9091                            }
9092                            if (!proc.pubProviders.containsKey(cpi.name)) {
9093                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9094                                proc.pubProviders.put(cpi.name, cpr);
9095                                try {
9096                                    proc.thread.scheduleInstallProvider(cpi);
9097                                } catch (RemoteException e) {
9098                                }
9099                            }
9100                        } else {
9101                            checkTime(startTime, "getContentProviderImpl: before start process");
9102                            proc = startProcessLocked(cpi.processName,
9103                                    cpr.appInfo, false, 0, "content provider",
9104                                    new ComponentName(cpi.applicationInfo.packageName,
9105                                            cpi.name), false, false, false);
9106                            checkTime(startTime, "getContentProviderImpl: after start process");
9107                            if (proc == null) {
9108                                Slog.w(TAG, "Unable to launch app "
9109                                        + cpi.applicationInfo.packageName + "/"
9110                                        + cpi.applicationInfo.uid + " for provider "
9111                                        + name + ": process is bad");
9112                                return null;
9113                            }
9114                        }
9115                        cpr.launchingApp = proc;
9116                        mLaunchingProviders.add(cpr);
9117                    } finally {
9118                        Binder.restoreCallingIdentity(origId);
9119                    }
9120                }
9121
9122                checkTime(startTime, "getContentProviderImpl: updating data structures");
9123
9124                // Make sure the provider is published (the same provider class
9125                // may be published under multiple names).
9126                if (firstClass) {
9127                    mProviderMap.putProviderByClass(comp, cpr);
9128                }
9129
9130                mProviderMap.putProviderByName(name, cpr);
9131                conn = incProviderCountLocked(r, cpr, token, stable);
9132                if (conn != null) {
9133                    conn.waiting = true;
9134                }
9135            }
9136            checkTime(startTime, "getContentProviderImpl: done!");
9137        }
9138
9139        // Wait for the provider to be published...
9140        synchronized (cpr) {
9141            while (cpr.provider == null) {
9142                if (cpr.launchingApp == null) {
9143                    Slog.w(TAG, "Unable to launch app "
9144                            + cpi.applicationInfo.packageName + "/"
9145                            + cpi.applicationInfo.uid + " for provider "
9146                            + name + ": launching app became null");
9147                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9148                            UserHandle.getUserId(cpi.applicationInfo.uid),
9149                            cpi.applicationInfo.packageName,
9150                            cpi.applicationInfo.uid, name);
9151                    return null;
9152                }
9153                try {
9154                    if (DEBUG_MU) {
9155                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9156                                + cpr.launchingApp);
9157                    }
9158                    if (conn != null) {
9159                        conn.waiting = true;
9160                    }
9161                    cpr.wait();
9162                } catch (InterruptedException ex) {
9163                } finally {
9164                    if (conn != null) {
9165                        conn.waiting = false;
9166                    }
9167                }
9168            }
9169        }
9170        return cpr != null ? cpr.newHolder(conn) : null;
9171    }
9172
9173    @Override
9174    public final ContentProviderHolder getContentProvider(
9175            IApplicationThread caller, String name, int userId, boolean stable) {
9176        enforceNotIsolatedCaller("getContentProvider");
9177        if (caller == null) {
9178            String msg = "null IApplicationThread when getting content provider "
9179                    + name;
9180            Slog.w(TAG, msg);
9181            throw new SecurityException(msg);
9182        }
9183        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9184        // with cross-user grant.
9185        return getContentProviderImpl(caller, name, null, stable, userId);
9186    }
9187
9188    public ContentProviderHolder getContentProviderExternal(
9189            String name, int userId, IBinder token) {
9190        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9191            "Do not have permission in call getContentProviderExternal()");
9192        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9193                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9194        return getContentProviderExternalUnchecked(name, token, userId);
9195    }
9196
9197    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9198            IBinder token, int userId) {
9199        return getContentProviderImpl(null, name, token, true, userId);
9200    }
9201
9202    /**
9203     * Drop a content provider from a ProcessRecord's bookkeeping
9204     */
9205    public void removeContentProvider(IBinder connection, boolean stable) {
9206        enforceNotIsolatedCaller("removeContentProvider");
9207        long ident = Binder.clearCallingIdentity();
9208        try {
9209            synchronized (this) {
9210                ContentProviderConnection conn;
9211                try {
9212                    conn = (ContentProviderConnection)connection;
9213                } catch (ClassCastException e) {
9214                    String msg ="removeContentProvider: " + connection
9215                            + " not a ContentProviderConnection";
9216                    Slog.w(TAG, msg);
9217                    throw new IllegalArgumentException(msg);
9218                }
9219                if (conn == null) {
9220                    throw new NullPointerException("connection is null");
9221                }
9222                if (decProviderCountLocked(conn, null, null, stable)) {
9223                    updateOomAdjLocked();
9224                }
9225            }
9226        } finally {
9227            Binder.restoreCallingIdentity(ident);
9228        }
9229    }
9230
9231    public void removeContentProviderExternal(String name, IBinder token) {
9232        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9233            "Do not have permission in call removeContentProviderExternal()");
9234        int userId = UserHandle.getCallingUserId();
9235        long ident = Binder.clearCallingIdentity();
9236        try {
9237            removeContentProviderExternalUnchecked(name, token, userId);
9238        } finally {
9239            Binder.restoreCallingIdentity(ident);
9240        }
9241    }
9242
9243    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9244        synchronized (this) {
9245            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9246            if(cpr == null) {
9247                //remove from mProvidersByClass
9248                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9249                return;
9250            }
9251
9252            //update content provider record entry info
9253            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9254            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9255            if (localCpr.hasExternalProcessHandles()) {
9256                if (localCpr.removeExternalProcessHandleLocked(token)) {
9257                    updateOomAdjLocked();
9258                } else {
9259                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9260                            + " with no external reference for token: "
9261                            + token + ".");
9262                }
9263            } else {
9264                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9265                        + " with no external references.");
9266            }
9267        }
9268    }
9269
9270    public final void publishContentProviders(IApplicationThread caller,
9271            List<ContentProviderHolder> providers) {
9272        if (providers == null) {
9273            return;
9274        }
9275
9276        enforceNotIsolatedCaller("publishContentProviders");
9277        synchronized (this) {
9278            final ProcessRecord r = getRecordForAppLocked(caller);
9279            if (DEBUG_MU)
9280                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9281            if (r == null) {
9282                throw new SecurityException(
9283                        "Unable to find app for caller " + caller
9284                      + " (pid=" + Binder.getCallingPid()
9285                      + ") when publishing content providers");
9286            }
9287
9288            final long origId = Binder.clearCallingIdentity();
9289
9290            final int N = providers.size();
9291            for (int i=0; i<N; i++) {
9292                ContentProviderHolder src = providers.get(i);
9293                if (src == null || src.info == null || src.provider == null) {
9294                    continue;
9295                }
9296                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9297                if (DEBUG_MU)
9298                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9299                if (dst != null) {
9300                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9301                    mProviderMap.putProviderByClass(comp, dst);
9302                    String names[] = dst.info.authority.split(";");
9303                    for (int j = 0; j < names.length; j++) {
9304                        mProviderMap.putProviderByName(names[j], dst);
9305                    }
9306
9307                    int NL = mLaunchingProviders.size();
9308                    int j;
9309                    for (j=0; j<NL; j++) {
9310                        if (mLaunchingProviders.get(j) == dst) {
9311                            mLaunchingProviders.remove(j);
9312                            j--;
9313                            NL--;
9314                        }
9315                    }
9316                    synchronized (dst) {
9317                        dst.provider = src.provider;
9318                        dst.proc = r;
9319                        dst.notifyAll();
9320                    }
9321                    updateOomAdjLocked(r);
9322                }
9323            }
9324
9325            Binder.restoreCallingIdentity(origId);
9326        }
9327    }
9328
9329    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9330        ContentProviderConnection conn;
9331        try {
9332            conn = (ContentProviderConnection)connection;
9333        } catch (ClassCastException e) {
9334            String msg ="refContentProvider: " + connection
9335                    + " not a ContentProviderConnection";
9336            Slog.w(TAG, msg);
9337            throw new IllegalArgumentException(msg);
9338        }
9339        if (conn == null) {
9340            throw new NullPointerException("connection is null");
9341        }
9342
9343        synchronized (this) {
9344            if (stable > 0) {
9345                conn.numStableIncs += stable;
9346            }
9347            stable = conn.stableCount + stable;
9348            if (stable < 0) {
9349                throw new IllegalStateException("stableCount < 0: " + stable);
9350            }
9351
9352            if (unstable > 0) {
9353                conn.numUnstableIncs += unstable;
9354            }
9355            unstable = conn.unstableCount + unstable;
9356            if (unstable < 0) {
9357                throw new IllegalStateException("unstableCount < 0: " + unstable);
9358            }
9359
9360            if ((stable+unstable) <= 0) {
9361                throw new IllegalStateException("ref counts can't go to zero here: stable="
9362                        + stable + " unstable=" + unstable);
9363            }
9364            conn.stableCount = stable;
9365            conn.unstableCount = unstable;
9366            return !conn.dead;
9367        }
9368    }
9369
9370    public void unstableProviderDied(IBinder connection) {
9371        ContentProviderConnection conn;
9372        try {
9373            conn = (ContentProviderConnection)connection;
9374        } catch (ClassCastException e) {
9375            String msg ="refContentProvider: " + connection
9376                    + " not a ContentProviderConnection";
9377            Slog.w(TAG, msg);
9378            throw new IllegalArgumentException(msg);
9379        }
9380        if (conn == null) {
9381            throw new NullPointerException("connection is null");
9382        }
9383
9384        // Safely retrieve the content provider associated with the connection.
9385        IContentProvider provider;
9386        synchronized (this) {
9387            provider = conn.provider.provider;
9388        }
9389
9390        if (provider == null) {
9391            // Um, yeah, we're way ahead of you.
9392            return;
9393        }
9394
9395        // Make sure the caller is being honest with us.
9396        if (provider.asBinder().pingBinder()) {
9397            // Er, no, still looks good to us.
9398            synchronized (this) {
9399                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9400                        + " says " + conn + " died, but we don't agree");
9401                return;
9402            }
9403        }
9404
9405        // Well look at that!  It's dead!
9406        synchronized (this) {
9407            if (conn.provider.provider != provider) {
9408                // But something changed...  good enough.
9409                return;
9410            }
9411
9412            ProcessRecord proc = conn.provider.proc;
9413            if (proc == null || proc.thread == null) {
9414                // Seems like the process is already cleaned up.
9415                return;
9416            }
9417
9418            // As far as we're concerned, this is just like receiving a
9419            // death notification...  just a bit prematurely.
9420            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9421                    + ") early provider death");
9422            final long ident = Binder.clearCallingIdentity();
9423            try {
9424                appDiedLocked(proc);
9425            } finally {
9426                Binder.restoreCallingIdentity(ident);
9427            }
9428        }
9429    }
9430
9431    @Override
9432    public void appNotRespondingViaProvider(IBinder connection) {
9433        enforceCallingPermission(
9434                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9435
9436        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9437        if (conn == null) {
9438            Slog.w(TAG, "ContentProviderConnection is null");
9439            return;
9440        }
9441
9442        final ProcessRecord host = conn.provider.proc;
9443        if (host == null) {
9444            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9445            return;
9446        }
9447
9448        final long token = Binder.clearCallingIdentity();
9449        try {
9450            appNotResponding(host, null, null, false, "ContentProvider not responding");
9451        } finally {
9452            Binder.restoreCallingIdentity(token);
9453        }
9454    }
9455
9456    public final void installSystemProviders() {
9457        List<ProviderInfo> providers;
9458        synchronized (this) {
9459            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9460            providers = generateApplicationProvidersLocked(app);
9461            if (providers != null) {
9462                for (int i=providers.size()-1; i>=0; i--) {
9463                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9464                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9465                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9466                                + ": not system .apk");
9467                        providers.remove(i);
9468                    }
9469                }
9470            }
9471        }
9472        if (providers != null) {
9473            mSystemThread.installSystemProviders(providers);
9474        }
9475
9476        mCoreSettingsObserver = new CoreSettingsObserver(this);
9477
9478        //mUsageStatsService.monitorPackages();
9479    }
9480
9481    /**
9482     * Allows apps to retrieve the MIME type of a URI.
9483     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9484     * users, then it does not need permission to access the ContentProvider.
9485     * Either, it needs cross-user uri grants.
9486     *
9487     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9488     *
9489     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9490     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9491     */
9492    public String getProviderMimeType(Uri uri, int userId) {
9493        enforceNotIsolatedCaller("getProviderMimeType");
9494        final String name = uri.getAuthority();
9495        int callingUid = Binder.getCallingUid();
9496        int callingPid = Binder.getCallingPid();
9497        long ident = 0;
9498        boolean clearedIdentity = false;
9499        userId = unsafeConvertIncomingUser(userId);
9500        if (canClearIdentity(callingPid, callingUid, userId)) {
9501            clearedIdentity = true;
9502            ident = Binder.clearCallingIdentity();
9503        }
9504        ContentProviderHolder holder = null;
9505        try {
9506            holder = getContentProviderExternalUnchecked(name, null, userId);
9507            if (holder != null) {
9508                return holder.provider.getType(uri);
9509            }
9510        } catch (RemoteException e) {
9511            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9512            return null;
9513        } finally {
9514            // We need to clear the identity to call removeContentProviderExternalUnchecked
9515            if (!clearedIdentity) {
9516                ident = Binder.clearCallingIdentity();
9517            }
9518            try {
9519                if (holder != null) {
9520                    removeContentProviderExternalUnchecked(name, null, userId);
9521                }
9522            } finally {
9523                Binder.restoreCallingIdentity(ident);
9524            }
9525        }
9526
9527        return null;
9528    }
9529
9530    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9531        if (UserHandle.getUserId(callingUid) == userId) {
9532            return true;
9533        }
9534        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9535                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9536                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9537                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9538                return true;
9539        }
9540        return false;
9541    }
9542
9543    // =========================================================
9544    // GLOBAL MANAGEMENT
9545    // =========================================================
9546
9547    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9548            boolean isolated, int isolatedUid) {
9549        String proc = customProcess != null ? customProcess : info.processName;
9550        BatteryStatsImpl.Uid.Proc ps = null;
9551        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9552        int uid = info.uid;
9553        if (isolated) {
9554            if (isolatedUid == 0) {
9555                int userId = UserHandle.getUserId(uid);
9556                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9557                while (true) {
9558                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9559                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9560                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9561                    }
9562                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9563                    mNextIsolatedProcessUid++;
9564                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9565                        // No process for this uid, use it.
9566                        break;
9567                    }
9568                    stepsLeft--;
9569                    if (stepsLeft <= 0) {
9570                        return null;
9571                    }
9572                }
9573            } else {
9574                // Special case for startIsolatedProcess (internal only), where
9575                // the uid of the isolated process is specified by the caller.
9576                uid = isolatedUid;
9577            }
9578        }
9579        return new ProcessRecord(stats, info, proc, uid);
9580    }
9581
9582    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9583            String abiOverride) {
9584        ProcessRecord app;
9585        if (!isolated) {
9586            app = getProcessRecordLocked(info.processName, info.uid, true);
9587        } else {
9588            app = null;
9589        }
9590
9591        if (app == null) {
9592            app = newProcessRecordLocked(info, null, isolated, 0);
9593            mProcessNames.put(info.processName, app.uid, app);
9594            if (isolated) {
9595                mIsolatedProcesses.put(app.uid, app);
9596            }
9597            updateLruProcessLocked(app, false, null);
9598            updateOomAdjLocked();
9599        }
9600
9601        // This package really, really can not be stopped.
9602        try {
9603            AppGlobals.getPackageManager().setPackageStoppedState(
9604                    info.packageName, false, UserHandle.getUserId(app.uid));
9605        } catch (RemoteException e) {
9606        } catch (IllegalArgumentException e) {
9607            Slog.w(TAG, "Failed trying to unstop package "
9608                    + info.packageName + ": " + e);
9609        }
9610
9611        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9612                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9613            app.persistent = true;
9614            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9615        }
9616        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9617            mPersistentStartingProcesses.add(app);
9618            startProcessLocked(app, "added application", app.processName, abiOverride,
9619                    null /* entryPoint */, null /* entryPointArgs */);
9620        }
9621
9622        return app;
9623    }
9624
9625    public void unhandledBack() {
9626        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9627                "unhandledBack()");
9628
9629        synchronized(this) {
9630            final long origId = Binder.clearCallingIdentity();
9631            try {
9632                getFocusedStack().unhandledBackLocked();
9633            } finally {
9634                Binder.restoreCallingIdentity(origId);
9635            }
9636        }
9637    }
9638
9639    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9640        enforceNotIsolatedCaller("openContentUri");
9641        final int userId = UserHandle.getCallingUserId();
9642        String name = uri.getAuthority();
9643        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9644        ParcelFileDescriptor pfd = null;
9645        if (cph != null) {
9646            // We record the binder invoker's uid in thread-local storage before
9647            // going to the content provider to open the file.  Later, in the code
9648            // that handles all permissions checks, we look for this uid and use
9649            // that rather than the Activity Manager's own uid.  The effect is that
9650            // we do the check against the caller's permissions even though it looks
9651            // to the content provider like the Activity Manager itself is making
9652            // the request.
9653            Binder token = new Binder();
9654            sCallerIdentity.set(new Identity(
9655                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9656            try {
9657                pfd = cph.provider.openFile(null, uri, "r", null, token);
9658            } catch (FileNotFoundException e) {
9659                // do nothing; pfd will be returned null
9660            } finally {
9661                // Ensure that whatever happens, we clean up the identity state
9662                sCallerIdentity.remove();
9663                // Ensure we're done with the provider.
9664                removeContentProviderExternalUnchecked(name, null, userId);
9665            }
9666        } else {
9667            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9668        }
9669        return pfd;
9670    }
9671
9672    // Actually is sleeping or shutting down or whatever else in the future
9673    // is an inactive state.
9674    public boolean isSleepingOrShuttingDown() {
9675        return isSleeping() || mShuttingDown;
9676    }
9677
9678    public boolean isSleeping() {
9679        return mSleeping;
9680    }
9681
9682    void onWakefulnessChanged(int wakefulness) {
9683        synchronized(this) {
9684            mWakefulness = wakefulness;
9685            updateSleepIfNeededLocked();
9686        }
9687    }
9688
9689    void finishRunningVoiceLocked() {
9690        if (mRunningVoice) {
9691            mRunningVoice = false;
9692            updateSleepIfNeededLocked();
9693        }
9694    }
9695
9696    void updateSleepIfNeededLocked() {
9697        if (mSleeping && !shouldSleepLocked()) {
9698            mSleeping = false;
9699            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9700        } else if (!mSleeping && shouldSleepLocked()) {
9701            mSleeping = true;
9702            mStackSupervisor.goingToSleepLocked();
9703
9704            // Initialize the wake times of all processes.
9705            checkExcessivePowerUsageLocked(false);
9706            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9707            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9708            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9709        }
9710    }
9711
9712    private boolean shouldSleepLocked() {
9713        // Resume applications while running a voice interactor.
9714        if (mRunningVoice) {
9715            return false;
9716        }
9717
9718        switch (mWakefulness) {
9719            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9720            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9721                // If we're interactive but applications are already paused then defer
9722                // resuming them until the lock screen is hidden.
9723                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9724            case PowerManagerInternal.WAKEFULNESS_DOZING:
9725                // If we're dozing then pause applications whenever the lock screen is shown.
9726                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9727            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9728            default:
9729                // If we're asleep then pause applications unconditionally.
9730                return true;
9731        }
9732    }
9733
9734    /** Pokes the task persister. */
9735    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9736        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9737            // Never persist the home stack.
9738            return;
9739        }
9740        mTaskPersister.wakeup(task, flush);
9741    }
9742
9743    /** Notifies all listeners when the task stack has changed. */
9744    void notifyTaskStackChangedLocked() {
9745        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9746        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9747        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9748    }
9749
9750    @Override
9751    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9752        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9753    }
9754
9755    @Override
9756    public boolean shutdown(int timeout) {
9757        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9758                != PackageManager.PERMISSION_GRANTED) {
9759            throw new SecurityException("Requires permission "
9760                    + android.Manifest.permission.SHUTDOWN);
9761        }
9762
9763        boolean timedout = false;
9764
9765        synchronized(this) {
9766            mShuttingDown = true;
9767            updateEventDispatchingLocked();
9768            timedout = mStackSupervisor.shutdownLocked(timeout);
9769        }
9770
9771        mAppOpsService.shutdown();
9772        if (mUsageStatsService != null) {
9773            mUsageStatsService.prepareShutdown();
9774        }
9775        mBatteryStatsService.shutdown();
9776        synchronized (this) {
9777            mProcessStats.shutdownLocked();
9778            notifyTaskPersisterLocked(null, true);
9779        }
9780
9781        return timedout;
9782    }
9783
9784    public final void activitySlept(IBinder token) {
9785        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
9786
9787        final long origId = Binder.clearCallingIdentity();
9788
9789        synchronized (this) {
9790            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9791            if (r != null) {
9792                mStackSupervisor.activitySleptLocked(r);
9793            }
9794        }
9795
9796        Binder.restoreCallingIdentity(origId);
9797    }
9798
9799    private String lockScreenShownToString() {
9800        switch (mLockScreenShown) {
9801            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9802            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9803            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9804            default: return "Unknown=" + mLockScreenShown;
9805        }
9806    }
9807
9808    void logLockScreen(String msg) {
9809        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9810                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9811                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9812                + " mSleeping=" + mSleeping);
9813    }
9814
9815    void startRunningVoiceLocked() {
9816        if (!mRunningVoice) {
9817            mRunningVoice = true;
9818            updateSleepIfNeededLocked();
9819        }
9820    }
9821
9822    private void updateEventDispatchingLocked() {
9823        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9824    }
9825
9826    public void setLockScreenShown(boolean shown) {
9827        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9828                != PackageManager.PERMISSION_GRANTED) {
9829            throw new SecurityException("Requires permission "
9830                    + android.Manifest.permission.DEVICE_POWER);
9831        }
9832
9833        synchronized(this) {
9834            long ident = Binder.clearCallingIdentity();
9835            try {
9836                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9837                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9838                updateSleepIfNeededLocked();
9839            } finally {
9840                Binder.restoreCallingIdentity(ident);
9841            }
9842        }
9843    }
9844
9845    @Override
9846    public void stopAppSwitches() {
9847        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9848                != PackageManager.PERMISSION_GRANTED) {
9849            throw new SecurityException("Requires permission "
9850                    + android.Manifest.permission.STOP_APP_SWITCHES);
9851        }
9852
9853        synchronized(this) {
9854            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9855                    + APP_SWITCH_DELAY_TIME;
9856            mDidAppSwitch = false;
9857            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9858            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9859            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9860        }
9861    }
9862
9863    public void resumeAppSwitches() {
9864        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9865                != PackageManager.PERMISSION_GRANTED) {
9866            throw new SecurityException("Requires permission "
9867                    + android.Manifest.permission.STOP_APP_SWITCHES);
9868        }
9869
9870        synchronized(this) {
9871            // Note that we don't execute any pending app switches... we will
9872            // let those wait until either the timeout, or the next start
9873            // activity request.
9874            mAppSwitchesAllowedTime = 0;
9875        }
9876    }
9877
9878    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9879            int callingPid, int callingUid, String name) {
9880        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9881            return true;
9882        }
9883
9884        int perm = checkComponentPermission(
9885                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9886                sourceUid, -1, true);
9887        if (perm == PackageManager.PERMISSION_GRANTED) {
9888            return true;
9889        }
9890
9891        // If the actual IPC caller is different from the logical source, then
9892        // also see if they are allowed to control app switches.
9893        if (callingUid != -1 && callingUid != sourceUid) {
9894            perm = checkComponentPermission(
9895                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9896                    callingUid, -1, true);
9897            if (perm == PackageManager.PERMISSION_GRANTED) {
9898                return true;
9899            }
9900        }
9901
9902        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9903        return false;
9904    }
9905
9906    public void setDebugApp(String packageName, boolean waitForDebugger,
9907            boolean persistent) {
9908        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9909                "setDebugApp()");
9910
9911        long ident = Binder.clearCallingIdentity();
9912        try {
9913            // Note that this is not really thread safe if there are multiple
9914            // callers into it at the same time, but that's not a situation we
9915            // care about.
9916            if (persistent) {
9917                final ContentResolver resolver = mContext.getContentResolver();
9918                Settings.Global.putString(
9919                    resolver, Settings.Global.DEBUG_APP,
9920                    packageName);
9921                Settings.Global.putInt(
9922                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9923                    waitForDebugger ? 1 : 0);
9924            }
9925
9926            synchronized (this) {
9927                if (!persistent) {
9928                    mOrigDebugApp = mDebugApp;
9929                    mOrigWaitForDebugger = mWaitForDebugger;
9930                }
9931                mDebugApp = packageName;
9932                mWaitForDebugger = waitForDebugger;
9933                mDebugTransient = !persistent;
9934                if (packageName != null) {
9935                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9936                            false, UserHandle.USER_ALL, "set debug app");
9937                }
9938            }
9939        } finally {
9940            Binder.restoreCallingIdentity(ident);
9941        }
9942    }
9943
9944    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9945        synchronized (this) {
9946            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9947            if (!isDebuggable) {
9948                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9949                    throw new SecurityException("Process not debuggable: " + app.packageName);
9950                }
9951            }
9952
9953            mOpenGlTraceApp = processName;
9954        }
9955    }
9956
9957    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9958        synchronized (this) {
9959            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9960            if (!isDebuggable) {
9961                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9962                    throw new SecurityException("Process not debuggable: " + app.packageName);
9963                }
9964            }
9965            mProfileApp = processName;
9966            mProfileFile = profilerInfo.profileFile;
9967            if (mProfileFd != null) {
9968                try {
9969                    mProfileFd.close();
9970                } catch (IOException e) {
9971                }
9972                mProfileFd = null;
9973            }
9974            mProfileFd = profilerInfo.profileFd;
9975            mSamplingInterval = profilerInfo.samplingInterval;
9976            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9977            mProfileType = 0;
9978        }
9979    }
9980
9981    @Override
9982    public void setAlwaysFinish(boolean enabled) {
9983        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9984                "setAlwaysFinish()");
9985
9986        Settings.Global.putInt(
9987                mContext.getContentResolver(),
9988                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9989
9990        synchronized (this) {
9991            mAlwaysFinishActivities = enabled;
9992        }
9993    }
9994
9995    @Override
9996    public void setActivityController(IActivityController controller) {
9997        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9998                "setActivityController()");
9999        synchronized (this) {
10000            mController = controller;
10001            Watchdog.getInstance().setActivityController(controller);
10002        }
10003    }
10004
10005    @Override
10006    public void setUserIsMonkey(boolean userIsMonkey) {
10007        synchronized (this) {
10008            synchronized (mPidsSelfLocked) {
10009                final int callingPid = Binder.getCallingPid();
10010                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10011                if (precessRecord == null) {
10012                    throw new SecurityException("Unknown process: " + callingPid);
10013                }
10014                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10015                    throw new SecurityException("Only an instrumentation process "
10016                            + "with a UiAutomation can call setUserIsMonkey");
10017                }
10018            }
10019            mUserIsMonkey = userIsMonkey;
10020        }
10021    }
10022
10023    @Override
10024    public boolean isUserAMonkey() {
10025        synchronized (this) {
10026            // If there is a controller also implies the user is a monkey.
10027            return (mUserIsMonkey || mController != null);
10028        }
10029    }
10030
10031    public void requestBugReport() {
10032        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10033        SystemProperties.set("ctl.start", "bugreport");
10034    }
10035
10036    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10037        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10038    }
10039
10040    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10041        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10042            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10043        }
10044        return KEY_DISPATCHING_TIMEOUT;
10045    }
10046
10047    @Override
10048    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10049        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10050                != PackageManager.PERMISSION_GRANTED) {
10051            throw new SecurityException("Requires permission "
10052                    + android.Manifest.permission.FILTER_EVENTS);
10053        }
10054        ProcessRecord proc;
10055        long timeout;
10056        synchronized (this) {
10057            synchronized (mPidsSelfLocked) {
10058                proc = mPidsSelfLocked.get(pid);
10059            }
10060            timeout = getInputDispatchingTimeoutLocked(proc);
10061        }
10062
10063        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10064            return -1;
10065        }
10066
10067        return timeout;
10068    }
10069
10070    /**
10071     * Handle input dispatching timeouts.
10072     * Returns whether input dispatching should be aborted or not.
10073     */
10074    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10075            final ActivityRecord activity, final ActivityRecord parent,
10076            final boolean aboveSystem, String reason) {
10077        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10078                != PackageManager.PERMISSION_GRANTED) {
10079            throw new SecurityException("Requires permission "
10080                    + android.Manifest.permission.FILTER_EVENTS);
10081        }
10082
10083        final String annotation;
10084        if (reason == null) {
10085            annotation = "Input dispatching timed out";
10086        } else {
10087            annotation = "Input dispatching timed out (" + reason + ")";
10088        }
10089
10090        if (proc != null) {
10091            synchronized (this) {
10092                if (proc.debugging) {
10093                    return false;
10094                }
10095
10096                if (mDidDexOpt) {
10097                    // Give more time since we were dexopting.
10098                    mDidDexOpt = false;
10099                    return false;
10100                }
10101
10102                if (proc.instrumentationClass != null) {
10103                    Bundle info = new Bundle();
10104                    info.putString("shortMsg", "keyDispatchingTimedOut");
10105                    info.putString("longMsg", annotation);
10106                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10107                    return true;
10108                }
10109            }
10110            mHandler.post(new Runnable() {
10111                @Override
10112                public void run() {
10113                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10114                }
10115            });
10116        }
10117
10118        return true;
10119    }
10120
10121    @Override
10122    public Bundle getAssistContextExtras(int requestType) {
10123        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10124                UserHandle.getCallingUserId());
10125        if (pae == null) {
10126            return null;
10127        }
10128        synchronized (pae) {
10129            while (!pae.haveResult) {
10130                try {
10131                    pae.wait();
10132                } catch (InterruptedException e) {
10133                }
10134            }
10135        }
10136        synchronized (this) {
10137            buildAssistBundleLocked(pae, pae.result);
10138            mPendingAssistExtras.remove(pae);
10139            mHandler.removeCallbacks(pae);
10140        }
10141        return pae.extras;
10142    }
10143
10144    @Override
10145    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10146        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10147    }
10148
10149    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10150            IResultReceiver receiver, int userHandle) {
10151        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10152                "getAssistContextExtras()");
10153        PendingAssistExtras pae;
10154        Bundle extras = new Bundle();
10155        synchronized (this) {
10156            ActivityRecord activity = getFocusedStack().mResumedActivity;
10157            if (activity == null) {
10158                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10159                return null;
10160            }
10161            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10162            if (activity.app == null || activity.app.thread == null) {
10163                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10164                return null;
10165            }
10166            if (activity.app.pid == Binder.getCallingPid()) {
10167                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10168                return null;
10169            }
10170            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10171            try {
10172                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10173                        requestType);
10174                mPendingAssistExtras.add(pae);
10175                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10176            } catch (RemoteException e) {
10177                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10178                return null;
10179            }
10180            return pae;
10181        }
10182    }
10183
10184    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10185        mPendingAssistExtras.remove(pae);
10186        if (pae.receiver != null) {
10187            // Caller wants result sent back to them.
10188            try {
10189                pae.receiver.send(0, null);
10190            } catch (RemoteException e) {
10191            }
10192        }
10193    }
10194
10195    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10196        if (result != null) {
10197            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10198        }
10199        if (pae.hint != null) {
10200            pae.extras.putBoolean(pae.hint, true);
10201        }
10202    }
10203
10204    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10205        PendingAssistExtras pae = (PendingAssistExtras)token;
10206        synchronized (pae) {
10207            pae.result = extras;
10208            pae.haveResult = true;
10209            pae.notifyAll();
10210            if (pae.intent == null && pae.receiver == null) {
10211                // Caller is just waiting for the result.
10212                return;
10213            }
10214        }
10215
10216        // We are now ready to launch the assist activity.
10217        synchronized (this) {
10218            buildAssistBundleLocked(pae, extras);
10219            boolean exists = mPendingAssistExtras.remove(pae);
10220            mHandler.removeCallbacks(pae);
10221            if (!exists) {
10222                // Timed out.
10223                return;
10224            }
10225            if (pae.receiver != null) {
10226                // Caller wants result sent back to them.
10227                try {
10228                    pae.receiver.send(0, pae.extras);
10229                } catch (RemoteException e) {
10230                }
10231                return;
10232            }
10233        }
10234        pae.intent.replaceExtras(pae.extras);
10235        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10236                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10237                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10238        closeSystemDialogs("assist");
10239        try {
10240            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10241        } catch (ActivityNotFoundException e) {
10242            Slog.w(TAG, "No activity to handle assist action.", e);
10243        }
10244    }
10245
10246    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10247        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10248    }
10249
10250    public void registerProcessObserver(IProcessObserver observer) {
10251        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10252                "registerProcessObserver()");
10253        synchronized (this) {
10254            mProcessObservers.register(observer);
10255        }
10256    }
10257
10258    @Override
10259    public void unregisterProcessObserver(IProcessObserver observer) {
10260        synchronized (this) {
10261            mProcessObservers.unregister(observer);
10262        }
10263    }
10264
10265    @Override
10266    public boolean convertFromTranslucent(IBinder token) {
10267        final long origId = Binder.clearCallingIdentity();
10268        try {
10269            synchronized (this) {
10270                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10271                if (r == null) {
10272                    return false;
10273                }
10274                final boolean translucentChanged = r.changeWindowTranslucency(true);
10275                if (translucentChanged) {
10276                    r.task.stack.releaseBackgroundResources(r);
10277                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10278                }
10279                mWindowManager.setAppFullscreen(token, true);
10280                return translucentChanged;
10281            }
10282        } finally {
10283            Binder.restoreCallingIdentity(origId);
10284        }
10285    }
10286
10287    @Override
10288    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10289        final long origId = Binder.clearCallingIdentity();
10290        try {
10291            synchronized (this) {
10292                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10293                if (r == null) {
10294                    return false;
10295                }
10296                int index = r.task.mActivities.lastIndexOf(r);
10297                if (index > 0) {
10298                    ActivityRecord under = r.task.mActivities.get(index - 1);
10299                    under.returningOptions = options;
10300                }
10301                final boolean translucentChanged = r.changeWindowTranslucency(false);
10302                if (translucentChanged) {
10303                    r.task.stack.convertActivityToTranslucent(r);
10304                }
10305                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10306                mWindowManager.setAppFullscreen(token, false);
10307                return translucentChanged;
10308            }
10309        } finally {
10310            Binder.restoreCallingIdentity(origId);
10311        }
10312    }
10313
10314    @Override
10315    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10316        final long origId = Binder.clearCallingIdentity();
10317        try {
10318            synchronized (this) {
10319                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10320                if (r != null) {
10321                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10322                }
10323            }
10324            return false;
10325        } finally {
10326            Binder.restoreCallingIdentity(origId);
10327        }
10328    }
10329
10330    @Override
10331    public boolean isBackgroundVisibleBehind(IBinder token) {
10332        final long origId = Binder.clearCallingIdentity();
10333        try {
10334            synchronized (this) {
10335                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10336                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10337                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10338                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10339                return visible;
10340            }
10341        } finally {
10342            Binder.restoreCallingIdentity(origId);
10343        }
10344    }
10345
10346    @Override
10347    public ActivityOptions getActivityOptions(IBinder token) {
10348        final long origId = Binder.clearCallingIdentity();
10349        try {
10350            synchronized (this) {
10351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10352                if (r != null) {
10353                    final ActivityOptions activityOptions = r.pendingOptions;
10354                    r.pendingOptions = null;
10355                    return activityOptions;
10356                }
10357                return null;
10358            }
10359        } finally {
10360            Binder.restoreCallingIdentity(origId);
10361        }
10362    }
10363
10364    @Override
10365    public void setImmersive(IBinder token, boolean immersive) {
10366        synchronized(this) {
10367            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10368            if (r == null) {
10369                throw new IllegalArgumentException();
10370            }
10371            r.immersive = immersive;
10372
10373            // update associated state if we're frontmost
10374            if (r == mFocusedActivity) {
10375                if (DEBUG_IMMERSIVE) {
10376                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10377                }
10378                applyUpdateLockStateLocked(r);
10379            }
10380        }
10381    }
10382
10383    @Override
10384    public boolean isImmersive(IBinder token) {
10385        synchronized (this) {
10386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10387            if (r == null) {
10388                throw new IllegalArgumentException();
10389            }
10390            return r.immersive;
10391        }
10392    }
10393
10394    public boolean isTopActivityImmersive() {
10395        enforceNotIsolatedCaller("startActivity");
10396        synchronized (this) {
10397            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10398            return (r != null) ? r.immersive : false;
10399        }
10400    }
10401
10402    @Override
10403    public boolean isTopOfTask(IBinder token) {
10404        synchronized (this) {
10405            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10406            if (r == null) {
10407                throw new IllegalArgumentException();
10408            }
10409            return r.task.getTopActivity() == r;
10410        }
10411    }
10412
10413    public final void enterSafeMode() {
10414        synchronized(this) {
10415            // It only makes sense to do this before the system is ready
10416            // and started launching other packages.
10417            if (!mSystemReady) {
10418                try {
10419                    AppGlobals.getPackageManager().enterSafeMode();
10420                } catch (RemoteException e) {
10421                }
10422            }
10423
10424            mSafeMode = true;
10425        }
10426    }
10427
10428    public final void showSafeModeOverlay() {
10429        View v = LayoutInflater.from(mContext).inflate(
10430                com.android.internal.R.layout.safe_mode, null);
10431        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10432        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10433        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10434        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10435        lp.gravity = Gravity.BOTTOM | Gravity.START;
10436        lp.format = v.getBackground().getOpacity();
10437        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10438                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10439        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10440        ((WindowManager)mContext.getSystemService(
10441                Context.WINDOW_SERVICE)).addView(v, lp);
10442    }
10443
10444    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10445        if (!(sender instanceof PendingIntentRecord)) {
10446            return;
10447        }
10448        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10449        synchronized (stats) {
10450            if (mBatteryStatsService.isOnBattery()) {
10451                mBatteryStatsService.enforceCallingPermission();
10452                PendingIntentRecord rec = (PendingIntentRecord)sender;
10453                int MY_UID = Binder.getCallingUid();
10454                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10455                BatteryStatsImpl.Uid.Pkg pkg =
10456                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10457                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10458                pkg.incWakeupsLocked();
10459            }
10460        }
10461    }
10462
10463    public boolean killPids(int[] pids, String pReason, boolean secure) {
10464        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10465            throw new SecurityException("killPids only available to the system");
10466        }
10467        String reason = (pReason == null) ? "Unknown" : pReason;
10468        // XXX Note: don't acquire main activity lock here, because the window
10469        // manager calls in with its locks held.
10470
10471        boolean killed = false;
10472        synchronized (mPidsSelfLocked) {
10473            int[] types = new int[pids.length];
10474            int worstType = 0;
10475            for (int i=0; i<pids.length; i++) {
10476                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10477                if (proc != null) {
10478                    int type = proc.setAdj;
10479                    types[i] = type;
10480                    if (type > worstType) {
10481                        worstType = type;
10482                    }
10483                }
10484            }
10485
10486            // If the worst oom_adj is somewhere in the cached proc LRU range,
10487            // then constrain it so we will kill all cached procs.
10488            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10489                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10490                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10491            }
10492
10493            // If this is not a secure call, don't let it kill processes that
10494            // are important.
10495            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10496                worstType = ProcessList.SERVICE_ADJ;
10497            }
10498
10499            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10500            for (int i=0; i<pids.length; i++) {
10501                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10502                if (proc == null) {
10503                    continue;
10504                }
10505                int adj = proc.setAdj;
10506                if (adj >= worstType && !proc.killedByAm) {
10507                    proc.kill(reason, true);
10508                    killed = true;
10509                }
10510            }
10511        }
10512        return killed;
10513    }
10514
10515    @Override
10516    public void killUid(int uid, String reason) {
10517        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10518            throw new SecurityException("killUid only available to the system");
10519        }
10520        synchronized (this) {
10521            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10522                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10523                    reason != null ? reason : "kill uid");
10524        }
10525    }
10526
10527    @Override
10528    public boolean killProcessesBelowForeground(String reason) {
10529        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10530            throw new SecurityException("killProcessesBelowForeground() only available to system");
10531        }
10532
10533        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10534    }
10535
10536    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10538            throw new SecurityException("killProcessesBelowAdj() only available to system");
10539        }
10540
10541        boolean killed = false;
10542        synchronized (mPidsSelfLocked) {
10543            final int size = mPidsSelfLocked.size();
10544            for (int i = 0; i < size; i++) {
10545                final int pid = mPidsSelfLocked.keyAt(i);
10546                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10547                if (proc == null) continue;
10548
10549                final int adj = proc.setAdj;
10550                if (adj > belowAdj && !proc.killedByAm) {
10551                    proc.kill(reason, true);
10552                    killed = true;
10553                }
10554            }
10555        }
10556        return killed;
10557    }
10558
10559    @Override
10560    public void hang(final IBinder who, boolean allowRestart) {
10561        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10562                != PackageManager.PERMISSION_GRANTED) {
10563            throw new SecurityException("Requires permission "
10564                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10565        }
10566
10567        final IBinder.DeathRecipient death = new DeathRecipient() {
10568            @Override
10569            public void binderDied() {
10570                synchronized (this) {
10571                    notifyAll();
10572                }
10573            }
10574        };
10575
10576        try {
10577            who.linkToDeath(death, 0);
10578        } catch (RemoteException e) {
10579            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10580            return;
10581        }
10582
10583        synchronized (this) {
10584            Watchdog.getInstance().setAllowRestart(allowRestart);
10585            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10586            synchronized (death) {
10587                while (who.isBinderAlive()) {
10588                    try {
10589                        death.wait();
10590                    } catch (InterruptedException e) {
10591                    }
10592                }
10593            }
10594            Watchdog.getInstance().setAllowRestart(true);
10595        }
10596    }
10597
10598    @Override
10599    public void restart() {
10600        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10601                != PackageManager.PERMISSION_GRANTED) {
10602            throw new SecurityException("Requires permission "
10603                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10604        }
10605
10606        Log.i(TAG, "Sending shutdown broadcast...");
10607
10608        BroadcastReceiver br = new BroadcastReceiver() {
10609            @Override public void onReceive(Context context, Intent intent) {
10610                // Now the broadcast is done, finish up the low-level shutdown.
10611                Log.i(TAG, "Shutting down activity manager...");
10612                shutdown(10000);
10613                Log.i(TAG, "Shutdown complete, restarting!");
10614                Process.killProcess(Process.myPid());
10615                System.exit(10);
10616            }
10617        };
10618
10619        // First send the high-level shut down broadcast.
10620        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10621        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10622        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10623        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10624        mContext.sendOrderedBroadcastAsUser(intent,
10625                UserHandle.ALL, null, br, mHandler, 0, null, null);
10626        */
10627        br.onReceive(mContext, intent);
10628    }
10629
10630    private long getLowRamTimeSinceIdle(long now) {
10631        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10632    }
10633
10634    @Override
10635    public void performIdleMaintenance() {
10636        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10637                != PackageManager.PERMISSION_GRANTED) {
10638            throw new SecurityException("Requires permission "
10639                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10640        }
10641
10642        synchronized (this) {
10643            final long now = SystemClock.uptimeMillis();
10644            final long timeSinceLastIdle = now - mLastIdleTime;
10645            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10646            mLastIdleTime = now;
10647            mLowRamTimeSinceLastIdle = 0;
10648            if (mLowRamStartTime != 0) {
10649                mLowRamStartTime = now;
10650            }
10651
10652            StringBuilder sb = new StringBuilder(128);
10653            sb.append("Idle maintenance over ");
10654            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10655            sb.append(" low RAM for ");
10656            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10657            Slog.i(TAG, sb.toString());
10658
10659            // If at least 1/3 of our time since the last idle period has been spent
10660            // with RAM low, then we want to kill processes.
10661            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10662
10663            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10664                ProcessRecord proc = mLruProcesses.get(i);
10665                if (proc.notCachedSinceIdle) {
10666                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10667                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10668                        if (doKilling && proc.initialIdlePss != 0
10669                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10670                            sb = new StringBuilder(128);
10671                            sb.append("Kill");
10672                            sb.append(proc.processName);
10673                            sb.append(" in idle maint: pss=");
10674                            sb.append(proc.lastPss);
10675                            sb.append(", initialPss=");
10676                            sb.append(proc.initialIdlePss);
10677                            sb.append(", period=");
10678                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10679                            sb.append(", lowRamPeriod=");
10680                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10681                            Slog.wtfQuiet(TAG, sb.toString());
10682                            proc.kill("idle maint (pss " + proc.lastPss
10683                                    + " from " + proc.initialIdlePss + ")", true);
10684                        }
10685                    }
10686                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10687                    proc.notCachedSinceIdle = true;
10688                    proc.initialIdlePss = 0;
10689                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10690                            mTestPssMode, isSleeping(), now);
10691                }
10692            }
10693
10694            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10695            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10696        }
10697    }
10698
10699    private void retrieveSettings() {
10700        final ContentResolver resolver = mContext.getContentResolver();
10701        String debugApp = Settings.Global.getString(
10702            resolver, Settings.Global.DEBUG_APP);
10703        boolean waitForDebugger = Settings.Global.getInt(
10704            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10705        boolean alwaysFinishActivities = Settings.Global.getInt(
10706            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10707        boolean forceRtl = Settings.Global.getInt(
10708                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10709        // Transfer any global setting for forcing RTL layout, into a System Property
10710        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10711
10712        Configuration configuration = new Configuration();
10713        Settings.System.getConfiguration(resolver, configuration);
10714        if (forceRtl) {
10715            // This will take care of setting the correct layout direction flags
10716            configuration.setLayoutDirection(configuration.locale);
10717        }
10718
10719        synchronized (this) {
10720            mDebugApp = mOrigDebugApp = debugApp;
10721            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10722            mAlwaysFinishActivities = alwaysFinishActivities;
10723            // This happens before any activities are started, so we can
10724            // change mConfiguration in-place.
10725            updateConfigurationLocked(configuration, null, false, true);
10726            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10727        }
10728    }
10729
10730    /** Loads resources after the current configuration has been set. */
10731    private void loadResourcesOnSystemReady() {
10732        final Resources res = mContext.getResources();
10733        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10734        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10735        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10736    }
10737
10738    public boolean testIsSystemReady() {
10739        // no need to synchronize(this) just to read & return the value
10740        return mSystemReady;
10741    }
10742
10743    private static File getCalledPreBootReceiversFile() {
10744        File dataDir = Environment.getDataDirectory();
10745        File systemDir = new File(dataDir, "system");
10746        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10747        return fname;
10748    }
10749
10750    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10751        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10752        File file = getCalledPreBootReceiversFile();
10753        FileInputStream fis = null;
10754        try {
10755            fis = new FileInputStream(file);
10756            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10757            int fvers = dis.readInt();
10758            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10759                String vers = dis.readUTF();
10760                String codename = dis.readUTF();
10761                String build = dis.readUTF();
10762                if (android.os.Build.VERSION.RELEASE.equals(vers)
10763                        && android.os.Build.VERSION.CODENAME.equals(codename)
10764                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10765                    int num = dis.readInt();
10766                    while (num > 0) {
10767                        num--;
10768                        String pkg = dis.readUTF();
10769                        String cls = dis.readUTF();
10770                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10771                    }
10772                }
10773            }
10774        } catch (FileNotFoundException e) {
10775        } catch (IOException e) {
10776            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10777        } finally {
10778            if (fis != null) {
10779                try {
10780                    fis.close();
10781                } catch (IOException e) {
10782                }
10783            }
10784        }
10785        return lastDoneReceivers;
10786    }
10787
10788    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10789        File file = getCalledPreBootReceiversFile();
10790        FileOutputStream fos = null;
10791        DataOutputStream dos = null;
10792        try {
10793            fos = new FileOutputStream(file);
10794            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10795            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10796            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10797            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10798            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10799            dos.writeInt(list.size());
10800            for (int i=0; i<list.size(); i++) {
10801                dos.writeUTF(list.get(i).getPackageName());
10802                dos.writeUTF(list.get(i).getClassName());
10803            }
10804        } catch (IOException e) {
10805            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10806            file.delete();
10807        } finally {
10808            FileUtils.sync(fos);
10809            if (dos != null) {
10810                try {
10811                    dos.close();
10812                } catch (IOException e) {
10813                    // TODO Auto-generated catch block
10814                    e.printStackTrace();
10815                }
10816            }
10817        }
10818    }
10819
10820    final class PreBootContinuation extends IIntentReceiver.Stub {
10821        final Intent intent;
10822        final Runnable onFinishCallback;
10823        final ArrayList<ComponentName> doneReceivers;
10824        final List<ResolveInfo> ris;
10825        final int[] users;
10826        int lastRi = -1;
10827        int curRi = 0;
10828        int curUser = 0;
10829
10830        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10831                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10832            intent = _intent;
10833            onFinishCallback = _onFinishCallback;
10834            doneReceivers = _doneReceivers;
10835            ris = _ris;
10836            users = _users;
10837        }
10838
10839        void go() {
10840            if (lastRi != curRi) {
10841                ActivityInfo ai = ris.get(curRi).activityInfo;
10842                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10843                intent.setComponent(comp);
10844                doneReceivers.add(comp);
10845                lastRi = curRi;
10846                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10847                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10848            }
10849            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10850                    + " for user " + users[curUser]);
10851            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10852            broadcastIntentLocked(null, null, intent, null, this,
10853                    0, null, null, null, AppOpsManager.OP_NONE,
10854                    true, false, MY_PID, Process.SYSTEM_UID,
10855                    users[curUser]);
10856        }
10857
10858        public void performReceive(Intent intent, int resultCode,
10859                String data, Bundle extras, boolean ordered,
10860                boolean sticky, int sendingUser) {
10861            curUser++;
10862            if (curUser >= users.length) {
10863                curUser = 0;
10864                curRi++;
10865                if (curRi >= ris.size()) {
10866                    // All done sending broadcasts!
10867                    if (onFinishCallback != null) {
10868                        // The raw IIntentReceiver interface is called
10869                        // with the AM lock held, so redispatch to
10870                        // execute our code without the lock.
10871                        mHandler.post(onFinishCallback);
10872                    }
10873                    return;
10874                }
10875            }
10876            go();
10877        }
10878    }
10879
10880    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10881            ArrayList<ComponentName> doneReceivers, int userId) {
10882        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10883        List<ResolveInfo> ris = null;
10884        try {
10885            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10886                    intent, null, 0, userId);
10887        } catch (RemoteException e) {
10888        }
10889        if (ris == null) {
10890            return false;
10891        }
10892        for (int i=ris.size()-1; i>=0; i--) {
10893            if ((ris.get(i).activityInfo.applicationInfo.flags
10894                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
10895                ris.remove(i);
10896            }
10897        }
10898        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10899
10900        // For User 0, load the version number. When delivering to a new user, deliver
10901        // to all receivers.
10902        if (userId == UserHandle.USER_OWNER) {
10903            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10904            for (int i=0; i<ris.size(); i++) {
10905                ActivityInfo ai = ris.get(i).activityInfo;
10906                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10907                if (false && lastDoneReceivers.contains(comp)) {
10908                    // We already did the pre boot receiver for this app with the current
10909                    // platform version, so don't do it again...
10910                    ris.remove(i);
10911                    i--;
10912                    // ...however, do keep it as one that has been done, so we don't
10913                    // forget about it when rewriting the file of last done receivers.
10914                    doneReceivers.add(comp);
10915                }
10916            }
10917        }
10918
10919        if (ris.size() <= 0) {
10920            return false;
10921        }
10922
10923        // If primary user, send broadcast to all available users, else just to userId
10924        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10925                : new int[] { userId };
10926        if (users.length <= 0) {
10927            return false;
10928        }
10929
10930        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
10931                ris, users);
10932        cont.go();
10933        return true;
10934    }
10935
10936    public void systemReady(final Runnable goingCallback) {
10937        synchronized(this) {
10938            if (mSystemReady) {
10939                // If we're done calling all the receivers, run the next "boot phase" passed in
10940                // by the SystemServer
10941                if (goingCallback != null) {
10942                    goingCallback.run();
10943                }
10944                return;
10945            }
10946
10947            // Make sure we have the current profile info, since it is needed for
10948            // security checks.
10949            updateCurrentProfileIdsLocked();
10950
10951            mRecentTasks.clear();
10952            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10953            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10954            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10955            mTaskPersister.startPersisting();
10956
10957            // Check to see if there are any update receivers to run.
10958            if (!mDidUpdate) {
10959                if (mWaitingUpdate) {
10960                    return;
10961                }
10962                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10963                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10964                    public void run() {
10965                        synchronized (ActivityManagerService.this) {
10966                            mDidUpdate = true;
10967                        }
10968                        showBootMessage(mContext.getText(
10969                                R.string.android_upgrading_complete),
10970                                false);
10971                        writeLastDonePreBootReceivers(doneReceivers);
10972                        systemReady(goingCallback);
10973                    }
10974                }, doneReceivers, UserHandle.USER_OWNER);
10975
10976                if (mWaitingUpdate) {
10977                    return;
10978                }
10979                mDidUpdate = true;
10980            }
10981
10982            mAppOpsService.systemReady();
10983            mSystemReady = true;
10984        }
10985
10986        ArrayList<ProcessRecord> procsToKill = null;
10987        synchronized(mPidsSelfLocked) {
10988            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10989                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10990                if (!isAllowedWhileBooting(proc.info)){
10991                    if (procsToKill == null) {
10992                        procsToKill = new ArrayList<ProcessRecord>();
10993                    }
10994                    procsToKill.add(proc);
10995                }
10996            }
10997        }
10998
10999        synchronized(this) {
11000            if (procsToKill != null) {
11001                for (int i=procsToKill.size()-1; i>=0; i--) {
11002                    ProcessRecord proc = procsToKill.get(i);
11003                    Slog.i(TAG, "Removing system update proc: " + proc);
11004                    removeProcessLocked(proc, true, false, "system update done");
11005                }
11006            }
11007
11008            // Now that we have cleaned up any update processes, we
11009            // are ready to start launching real processes and know that
11010            // we won't trample on them any more.
11011            mProcessesReady = true;
11012        }
11013
11014        Slog.i(TAG, "System now ready");
11015        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11016            SystemClock.uptimeMillis());
11017
11018        synchronized(this) {
11019            // Make sure we have no pre-ready processes sitting around.
11020
11021            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11022                ResolveInfo ri = mContext.getPackageManager()
11023                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11024                                STOCK_PM_FLAGS);
11025                CharSequence errorMsg = null;
11026                if (ri != null) {
11027                    ActivityInfo ai = ri.activityInfo;
11028                    ApplicationInfo app = ai.applicationInfo;
11029                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11030                        mTopAction = Intent.ACTION_FACTORY_TEST;
11031                        mTopData = null;
11032                        mTopComponent = new ComponentName(app.packageName,
11033                                ai.name);
11034                    } else {
11035                        errorMsg = mContext.getResources().getText(
11036                                com.android.internal.R.string.factorytest_not_system);
11037                    }
11038                } else {
11039                    errorMsg = mContext.getResources().getText(
11040                            com.android.internal.R.string.factorytest_no_action);
11041                }
11042                if (errorMsg != null) {
11043                    mTopAction = null;
11044                    mTopData = null;
11045                    mTopComponent = null;
11046                    Message msg = Message.obtain();
11047                    msg.what = SHOW_FACTORY_ERROR_MSG;
11048                    msg.getData().putCharSequence("msg", errorMsg);
11049                    mHandler.sendMessage(msg);
11050                }
11051            }
11052        }
11053
11054        retrieveSettings();
11055        loadResourcesOnSystemReady();
11056
11057        synchronized (this) {
11058            readGrantedUriPermissionsLocked();
11059        }
11060
11061        if (goingCallback != null) goingCallback.run();
11062
11063        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11064                Integer.toString(mCurrentUserId), mCurrentUserId);
11065        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11066                Integer.toString(mCurrentUserId), mCurrentUserId);
11067        mSystemServiceManager.startUser(mCurrentUserId);
11068
11069        synchronized (this) {
11070            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11071                try {
11072                    List apps = AppGlobals.getPackageManager().
11073                        getPersistentApplications(STOCK_PM_FLAGS);
11074                    if (apps != null) {
11075                        int N = apps.size();
11076                        int i;
11077                        for (i=0; i<N; i++) {
11078                            ApplicationInfo info
11079                                = (ApplicationInfo)apps.get(i);
11080                            if (info != null &&
11081                                    !info.packageName.equals("android")) {
11082                                addAppLocked(info, false, null /* ABI override */);
11083                            }
11084                        }
11085                    }
11086                } catch (RemoteException ex) {
11087                    // pm is in same process, this will never happen.
11088                }
11089            }
11090
11091            // Start up initial activity.
11092            mBooting = true;
11093            startHomeActivityLocked(mCurrentUserId, "systemReady");
11094
11095            try {
11096                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11097                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11098                            + " data partition or your device will be unstable.");
11099                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11100                }
11101            } catch (RemoteException e) {
11102            }
11103
11104            if (!Build.isBuildConsistent()) {
11105                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11106                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11107            }
11108
11109            long ident = Binder.clearCallingIdentity();
11110            try {
11111                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11112                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11113                        | Intent.FLAG_RECEIVER_FOREGROUND);
11114                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11115                broadcastIntentLocked(null, null, intent,
11116                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11117                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11118                intent = new Intent(Intent.ACTION_USER_STARTING);
11119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11120                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11121                broadcastIntentLocked(null, null, intent,
11122                        null, new IIntentReceiver.Stub() {
11123                            @Override
11124                            public void performReceive(Intent intent, int resultCode, String data,
11125                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11126                                    throws RemoteException {
11127                            }
11128                        }, 0, null, null,
11129                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11130                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11131            } catch (Throwable t) {
11132                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11133            } finally {
11134                Binder.restoreCallingIdentity(ident);
11135            }
11136            mStackSupervisor.resumeTopActivitiesLocked();
11137            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11138        }
11139    }
11140
11141    private boolean makeAppCrashingLocked(ProcessRecord app,
11142            String shortMsg, String longMsg, String stackTrace) {
11143        app.crashing = true;
11144        app.crashingReport = generateProcessError(app,
11145                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11146        startAppProblemLocked(app);
11147        app.stopFreezingAllLocked();
11148        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11149    }
11150
11151    private void makeAppNotRespondingLocked(ProcessRecord app,
11152            String activity, String shortMsg, String longMsg) {
11153        app.notResponding = true;
11154        app.notRespondingReport = generateProcessError(app,
11155                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11156                activity, shortMsg, longMsg, null);
11157        startAppProblemLocked(app);
11158        app.stopFreezingAllLocked();
11159    }
11160
11161    /**
11162     * Generate a process error record, suitable for attachment to a ProcessRecord.
11163     *
11164     * @param app The ProcessRecord in which the error occurred.
11165     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11166     *                      ActivityManager.AppErrorStateInfo
11167     * @param activity The activity associated with the crash, if known.
11168     * @param shortMsg Short message describing the crash.
11169     * @param longMsg Long message describing the crash.
11170     * @param stackTrace Full crash stack trace, may be null.
11171     *
11172     * @return Returns a fully-formed AppErrorStateInfo record.
11173     */
11174    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11175            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11176        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11177
11178        report.condition = condition;
11179        report.processName = app.processName;
11180        report.pid = app.pid;
11181        report.uid = app.info.uid;
11182        report.tag = activity;
11183        report.shortMsg = shortMsg;
11184        report.longMsg = longMsg;
11185        report.stackTrace = stackTrace;
11186
11187        return report;
11188    }
11189
11190    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11191        synchronized (this) {
11192            app.crashing = false;
11193            app.crashingReport = null;
11194            app.notResponding = false;
11195            app.notRespondingReport = null;
11196            if (app.anrDialog == fromDialog) {
11197                app.anrDialog = null;
11198            }
11199            if (app.waitDialog == fromDialog) {
11200                app.waitDialog = null;
11201            }
11202            if (app.pid > 0 && app.pid != MY_PID) {
11203                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11204                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11205                app.kill("user request after error", true);
11206            }
11207        }
11208    }
11209
11210    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11211            String shortMsg, String longMsg, String stackTrace) {
11212        long now = SystemClock.uptimeMillis();
11213
11214        Long crashTime;
11215        if (!app.isolated) {
11216            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11217        } else {
11218            crashTime = null;
11219        }
11220        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11221            // This process loses!
11222            Slog.w(TAG, "Process " + app.info.processName
11223                    + " has crashed too many times: killing!");
11224            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11225                    app.userId, app.info.processName, app.uid);
11226            mStackSupervisor.handleAppCrashLocked(app);
11227            if (!app.persistent) {
11228                // We don't want to start this process again until the user
11229                // explicitly does so...  but for persistent process, we really
11230                // need to keep it running.  If a persistent process is actually
11231                // repeatedly crashing, then badness for everyone.
11232                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11233                        app.info.processName);
11234                if (!app.isolated) {
11235                    // XXX We don't have a way to mark isolated processes
11236                    // as bad, since they don't have a peristent identity.
11237                    mBadProcesses.put(app.info.processName, app.uid,
11238                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11239                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11240                }
11241                app.bad = true;
11242                app.removed = true;
11243                // Don't let services in this process be restarted and potentially
11244                // annoy the user repeatedly.  Unless it is persistent, since those
11245                // processes run critical code.
11246                removeProcessLocked(app, false, false, "crash");
11247                mStackSupervisor.resumeTopActivitiesLocked();
11248                return false;
11249            }
11250            mStackSupervisor.resumeTopActivitiesLocked();
11251        } else {
11252            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11253        }
11254
11255        // Bump up the crash count of any services currently running in the proc.
11256        for (int i=app.services.size()-1; i>=0; i--) {
11257            // Any services running in the application need to be placed
11258            // back in the pending list.
11259            ServiceRecord sr = app.services.valueAt(i);
11260            sr.crashCount++;
11261        }
11262
11263        // If the crashing process is what we consider to be the "home process" and it has been
11264        // replaced by a third-party app, clear the package preferred activities from packages
11265        // with a home activity running in the process to prevent a repeatedly crashing app
11266        // from blocking the user to manually clear the list.
11267        final ArrayList<ActivityRecord> activities = app.activities;
11268        if (app == mHomeProcess && activities.size() > 0
11269                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11270            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11271                final ActivityRecord r = activities.get(activityNdx);
11272                if (r.isHomeActivity()) {
11273                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11274                    try {
11275                        ActivityThread.getPackageManager()
11276                                .clearPackagePreferredActivities(r.packageName);
11277                    } catch (RemoteException c) {
11278                        // pm is in same process, this will never happen.
11279                    }
11280                }
11281            }
11282        }
11283
11284        if (!app.isolated) {
11285            // XXX Can't keep track of crash times for isolated processes,
11286            // because they don't have a perisistent identity.
11287            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11288        }
11289
11290        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11291        return true;
11292    }
11293
11294    void startAppProblemLocked(ProcessRecord app) {
11295        // If this app is not running under the current user, then we
11296        // can't give it a report button because that would require
11297        // launching the report UI under a different user.
11298        app.errorReportReceiver = null;
11299
11300        for (int userId : mCurrentProfileIds) {
11301            if (app.userId == userId) {
11302                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11303                        mContext, app.info.packageName, app.info.flags);
11304            }
11305        }
11306        skipCurrentReceiverLocked(app);
11307    }
11308
11309    void skipCurrentReceiverLocked(ProcessRecord app) {
11310        for (BroadcastQueue queue : mBroadcastQueues) {
11311            queue.skipCurrentReceiverLocked(app);
11312        }
11313    }
11314
11315    /**
11316     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11317     * The application process will exit immediately after this call returns.
11318     * @param app object of the crashing app, null for the system server
11319     * @param crashInfo describing the exception
11320     */
11321    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11322        ProcessRecord r = findAppProcess(app, "Crash");
11323        final String processName = app == null ? "system_server"
11324                : (r == null ? "unknown" : r.processName);
11325
11326        handleApplicationCrashInner("crash", r, processName, crashInfo);
11327    }
11328
11329    /* Native crash reporting uses this inner version because it needs to be somewhat
11330     * decoupled from the AM-managed cleanup lifecycle
11331     */
11332    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11333            ApplicationErrorReport.CrashInfo crashInfo) {
11334        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11335                UserHandle.getUserId(Binder.getCallingUid()), processName,
11336                r == null ? -1 : r.info.flags,
11337                crashInfo.exceptionClassName,
11338                crashInfo.exceptionMessage,
11339                crashInfo.throwFileName,
11340                crashInfo.throwLineNumber);
11341
11342        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11343
11344        crashApplication(r, crashInfo);
11345    }
11346
11347    public void handleApplicationStrictModeViolation(
11348            IBinder app,
11349            int violationMask,
11350            StrictMode.ViolationInfo info) {
11351        ProcessRecord r = findAppProcess(app, "StrictMode");
11352        if (r == null) {
11353            return;
11354        }
11355
11356        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11357            Integer stackFingerprint = info.hashCode();
11358            boolean logIt = true;
11359            synchronized (mAlreadyLoggedViolatedStacks) {
11360                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11361                    logIt = false;
11362                    // TODO: sub-sample into EventLog for these, with
11363                    // the info.durationMillis?  Then we'd get
11364                    // the relative pain numbers, without logging all
11365                    // the stack traces repeatedly.  We'd want to do
11366                    // likewise in the client code, which also does
11367                    // dup suppression, before the Binder call.
11368                } else {
11369                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11370                        mAlreadyLoggedViolatedStacks.clear();
11371                    }
11372                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11373                }
11374            }
11375            if (logIt) {
11376                logStrictModeViolationToDropBox(r, info);
11377            }
11378        }
11379
11380        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11381            AppErrorResult result = new AppErrorResult();
11382            synchronized (this) {
11383                final long origId = Binder.clearCallingIdentity();
11384
11385                Message msg = Message.obtain();
11386                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11387                HashMap<String, Object> data = new HashMap<String, Object>();
11388                data.put("result", result);
11389                data.put("app", r);
11390                data.put("violationMask", violationMask);
11391                data.put("info", info);
11392                msg.obj = data;
11393                mHandler.sendMessage(msg);
11394
11395                Binder.restoreCallingIdentity(origId);
11396            }
11397            int res = result.get();
11398            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11399        }
11400    }
11401
11402    // Depending on the policy in effect, there could be a bunch of
11403    // these in quick succession so we try to batch these together to
11404    // minimize disk writes, number of dropbox entries, and maximize
11405    // compression, by having more fewer, larger records.
11406    private void logStrictModeViolationToDropBox(
11407            ProcessRecord process,
11408            StrictMode.ViolationInfo info) {
11409        if (info == null) {
11410            return;
11411        }
11412        final boolean isSystemApp = process == null ||
11413                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11414                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11415        final String processName = process == null ? "unknown" : process.processName;
11416        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11417        final DropBoxManager dbox = (DropBoxManager)
11418                mContext.getSystemService(Context.DROPBOX_SERVICE);
11419
11420        // Exit early if the dropbox isn't configured to accept this report type.
11421        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11422
11423        boolean bufferWasEmpty;
11424        boolean needsFlush;
11425        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11426        synchronized (sb) {
11427            bufferWasEmpty = sb.length() == 0;
11428            appendDropBoxProcessHeaders(process, processName, sb);
11429            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11430            sb.append("System-App: ").append(isSystemApp).append("\n");
11431            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11432            if (info.violationNumThisLoop != 0) {
11433                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11434            }
11435            if (info.numAnimationsRunning != 0) {
11436                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11437            }
11438            if (info.broadcastIntentAction != null) {
11439                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11440            }
11441            if (info.durationMillis != -1) {
11442                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11443            }
11444            if (info.numInstances != -1) {
11445                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11446            }
11447            if (info.tags != null) {
11448                for (String tag : info.tags) {
11449                    sb.append("Span-Tag: ").append(tag).append("\n");
11450                }
11451            }
11452            sb.append("\n");
11453            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11454                sb.append(info.crashInfo.stackTrace);
11455                sb.append("\n");
11456            }
11457            if (info.message != null) {
11458                sb.append(info.message);
11459                sb.append("\n");
11460            }
11461
11462            // Only buffer up to ~64k.  Various logging bits truncate
11463            // things at 128k.
11464            needsFlush = (sb.length() > 64 * 1024);
11465        }
11466
11467        // Flush immediately if the buffer's grown too large, or this
11468        // is a non-system app.  Non-system apps are isolated with a
11469        // different tag & policy and not batched.
11470        //
11471        // Batching is useful during internal testing with
11472        // StrictMode settings turned up high.  Without batching,
11473        // thousands of separate files could be created on boot.
11474        if (!isSystemApp || needsFlush) {
11475            new Thread("Error dump: " + dropboxTag) {
11476                @Override
11477                public void run() {
11478                    String report;
11479                    synchronized (sb) {
11480                        report = sb.toString();
11481                        sb.delete(0, sb.length());
11482                        sb.trimToSize();
11483                    }
11484                    if (report.length() != 0) {
11485                        dbox.addText(dropboxTag, report);
11486                    }
11487                }
11488            }.start();
11489            return;
11490        }
11491
11492        // System app batching:
11493        if (!bufferWasEmpty) {
11494            // An existing dropbox-writing thread is outstanding, so
11495            // we don't need to start it up.  The existing thread will
11496            // catch the buffer appends we just did.
11497            return;
11498        }
11499
11500        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11501        // (After this point, we shouldn't access AMS internal data structures.)
11502        new Thread("Error dump: " + dropboxTag) {
11503            @Override
11504            public void run() {
11505                // 5 second sleep to let stacks arrive and be batched together
11506                try {
11507                    Thread.sleep(5000);  // 5 seconds
11508                } catch (InterruptedException e) {}
11509
11510                String errorReport;
11511                synchronized (mStrictModeBuffer) {
11512                    errorReport = mStrictModeBuffer.toString();
11513                    if (errorReport.length() == 0) {
11514                        return;
11515                    }
11516                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11517                    mStrictModeBuffer.trimToSize();
11518                }
11519                dbox.addText(dropboxTag, errorReport);
11520            }
11521        }.start();
11522    }
11523
11524    /**
11525     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11526     * @param app object of the crashing app, null for the system server
11527     * @param tag reported by the caller
11528     * @param system whether this wtf is coming from the system
11529     * @param crashInfo describing the context of the error
11530     * @return true if the process should exit immediately (WTF is fatal)
11531     */
11532    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11533            final ApplicationErrorReport.CrashInfo crashInfo) {
11534        final int callingUid = Binder.getCallingUid();
11535        final int callingPid = Binder.getCallingPid();
11536
11537        if (system) {
11538            // If this is coming from the system, we could very well have low-level
11539            // system locks held, so we want to do this all asynchronously.  And we
11540            // never want this to become fatal, so there is that too.
11541            mHandler.post(new Runnable() {
11542                @Override public void run() {
11543                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11544                }
11545            });
11546            return false;
11547        }
11548
11549        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11550                crashInfo);
11551
11552        if (r != null && r.pid != Process.myPid() &&
11553                Settings.Global.getInt(mContext.getContentResolver(),
11554                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11555            crashApplication(r, crashInfo);
11556            return true;
11557        } else {
11558            return false;
11559        }
11560    }
11561
11562    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11563            final ApplicationErrorReport.CrashInfo crashInfo) {
11564        final ProcessRecord r = findAppProcess(app, "WTF");
11565        final String processName = app == null ? "system_server"
11566                : (r == null ? "unknown" : r.processName);
11567
11568        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11569                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11570
11571        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11572
11573        return r;
11574    }
11575
11576    /**
11577     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11578     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11579     */
11580    private ProcessRecord findAppProcess(IBinder app, String reason) {
11581        if (app == null) {
11582            return null;
11583        }
11584
11585        synchronized (this) {
11586            final int NP = mProcessNames.getMap().size();
11587            for (int ip=0; ip<NP; ip++) {
11588                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11589                final int NA = apps.size();
11590                for (int ia=0; ia<NA; ia++) {
11591                    ProcessRecord p = apps.valueAt(ia);
11592                    if (p.thread != null && p.thread.asBinder() == app) {
11593                        return p;
11594                    }
11595                }
11596            }
11597
11598            Slog.w(TAG, "Can't find mystery application for " + reason
11599                    + " from pid=" + Binder.getCallingPid()
11600                    + " uid=" + Binder.getCallingUid() + ": " + app);
11601            return null;
11602        }
11603    }
11604
11605    /**
11606     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11607     * to append various headers to the dropbox log text.
11608     */
11609    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11610            StringBuilder sb) {
11611        // Watchdog thread ends up invoking this function (with
11612        // a null ProcessRecord) to add the stack file to dropbox.
11613        // Do not acquire a lock on this (am) in such cases, as it
11614        // could cause a potential deadlock, if and when watchdog
11615        // is invoked due to unavailability of lock on am and it
11616        // would prevent watchdog from killing system_server.
11617        if (process == null) {
11618            sb.append("Process: ").append(processName).append("\n");
11619            return;
11620        }
11621        // Note: ProcessRecord 'process' is guarded by the service
11622        // instance.  (notably process.pkgList, which could otherwise change
11623        // concurrently during execution of this method)
11624        synchronized (this) {
11625            sb.append("Process: ").append(processName).append("\n");
11626            int flags = process.info.flags;
11627            IPackageManager pm = AppGlobals.getPackageManager();
11628            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11629            for (int ip=0; ip<process.pkgList.size(); ip++) {
11630                String pkg = process.pkgList.keyAt(ip);
11631                sb.append("Package: ").append(pkg);
11632                try {
11633                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11634                    if (pi != null) {
11635                        sb.append(" v").append(pi.versionCode);
11636                        if (pi.versionName != null) {
11637                            sb.append(" (").append(pi.versionName).append(")");
11638                        }
11639                    }
11640                } catch (RemoteException e) {
11641                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11642                }
11643                sb.append("\n");
11644            }
11645        }
11646    }
11647
11648    private static String processClass(ProcessRecord process) {
11649        if (process == null || process.pid == MY_PID) {
11650            return "system_server";
11651        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11652            return "system_app";
11653        } else {
11654            return "data_app";
11655        }
11656    }
11657
11658    /**
11659     * Write a description of an error (crash, WTF, ANR) to the drop box.
11660     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11661     * @param process which caused the error, null means the system server
11662     * @param activity which triggered the error, null if unknown
11663     * @param parent activity related to the error, null if unknown
11664     * @param subject line related to the error, null if absent
11665     * @param report in long form describing the error, null if absent
11666     * @param logFile to include in the report, null if none
11667     * @param crashInfo giving an application stack trace, null if absent
11668     */
11669    public void addErrorToDropBox(String eventType,
11670            ProcessRecord process, String processName, ActivityRecord activity,
11671            ActivityRecord parent, String subject,
11672            final String report, final File logFile,
11673            final ApplicationErrorReport.CrashInfo crashInfo) {
11674        // NOTE -- this must never acquire the ActivityManagerService lock,
11675        // otherwise the watchdog may be prevented from resetting the system.
11676
11677        final String dropboxTag = processClass(process) + "_" + eventType;
11678        final DropBoxManager dbox = (DropBoxManager)
11679                mContext.getSystemService(Context.DROPBOX_SERVICE);
11680
11681        // Exit early if the dropbox isn't configured to accept this report type.
11682        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11683
11684        final StringBuilder sb = new StringBuilder(1024);
11685        appendDropBoxProcessHeaders(process, processName, sb);
11686        if (activity != null) {
11687            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11688        }
11689        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11690            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11691        }
11692        if (parent != null && parent != activity) {
11693            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11694        }
11695        if (subject != null) {
11696            sb.append("Subject: ").append(subject).append("\n");
11697        }
11698        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11699        if (Debug.isDebuggerConnected()) {
11700            sb.append("Debugger: Connected\n");
11701        }
11702        sb.append("\n");
11703
11704        // Do the rest in a worker thread to avoid blocking the caller on I/O
11705        // (After this point, we shouldn't access AMS internal data structures.)
11706        Thread worker = new Thread("Error dump: " + dropboxTag) {
11707            @Override
11708            public void run() {
11709                if (report != null) {
11710                    sb.append(report);
11711                }
11712                if (logFile != null) {
11713                    try {
11714                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11715                                    "\n\n[[TRUNCATED]]"));
11716                    } catch (IOException e) {
11717                        Slog.e(TAG, "Error reading " + logFile, e);
11718                    }
11719                }
11720                if (crashInfo != null && crashInfo.stackTrace != null) {
11721                    sb.append(crashInfo.stackTrace);
11722                }
11723
11724                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11725                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11726                if (lines > 0) {
11727                    sb.append("\n");
11728
11729                    // Merge several logcat streams, and take the last N lines
11730                    InputStreamReader input = null;
11731                    try {
11732                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11733                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11734                                "-b", "crash",
11735                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11736
11737                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11738                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11739                        input = new InputStreamReader(logcat.getInputStream());
11740
11741                        int num;
11742                        char[] buf = new char[8192];
11743                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11744                    } catch (IOException e) {
11745                        Slog.e(TAG, "Error running logcat", e);
11746                    } finally {
11747                        if (input != null) try { input.close(); } catch (IOException e) {}
11748                    }
11749                }
11750
11751                dbox.addText(dropboxTag, sb.toString());
11752            }
11753        };
11754
11755        if (process == null) {
11756            // If process is null, we are being called from some internal code
11757            // and may be about to die -- run this synchronously.
11758            worker.run();
11759        } else {
11760            worker.start();
11761        }
11762    }
11763
11764    /**
11765     * Bring up the "unexpected error" dialog box for a crashing app.
11766     * Deal with edge cases (intercepts from instrumented applications,
11767     * ActivityController, error intent receivers, that sort of thing).
11768     * @param r the application crashing
11769     * @param crashInfo describing the failure
11770     */
11771    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11772        long timeMillis = System.currentTimeMillis();
11773        String shortMsg = crashInfo.exceptionClassName;
11774        String longMsg = crashInfo.exceptionMessage;
11775        String stackTrace = crashInfo.stackTrace;
11776        if (shortMsg != null && longMsg != null) {
11777            longMsg = shortMsg + ": " + longMsg;
11778        } else if (shortMsg != null) {
11779            longMsg = shortMsg;
11780        }
11781
11782        AppErrorResult result = new AppErrorResult();
11783        synchronized (this) {
11784            if (mController != null) {
11785                try {
11786                    String name = r != null ? r.processName : null;
11787                    int pid = r != null ? r.pid : Binder.getCallingPid();
11788                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11789                    if (!mController.appCrashed(name, pid,
11790                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11791                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11792                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11793                            Slog.w(TAG, "Skip killing native crashed app " + name
11794                                    + "(" + pid + ") during testing");
11795                        } else {
11796                            Slog.w(TAG, "Force-killing crashed app " + name
11797                                    + " at watcher's request");
11798                            if (r != null) {
11799                                r.kill("crash", true);
11800                            } else {
11801                                // Huh.
11802                                Process.killProcess(pid);
11803                                Process.killProcessGroup(uid, pid);
11804                            }
11805                        }
11806                        return;
11807                    }
11808                } catch (RemoteException e) {
11809                    mController = null;
11810                    Watchdog.getInstance().setActivityController(null);
11811                }
11812            }
11813
11814            final long origId = Binder.clearCallingIdentity();
11815
11816            // If this process is running instrumentation, finish it.
11817            if (r != null && r.instrumentationClass != null) {
11818                Slog.w(TAG, "Error in app " + r.processName
11819                      + " running instrumentation " + r.instrumentationClass + ":");
11820                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11821                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11822                Bundle info = new Bundle();
11823                info.putString("shortMsg", shortMsg);
11824                info.putString("longMsg", longMsg);
11825                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11826                Binder.restoreCallingIdentity(origId);
11827                return;
11828            }
11829
11830            // Log crash in battery stats.
11831            if (r != null) {
11832                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11833            }
11834
11835            // If we can't identify the process or it's already exceeded its crash quota,
11836            // quit right away without showing a crash dialog.
11837            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11838                Binder.restoreCallingIdentity(origId);
11839                return;
11840            }
11841
11842            Message msg = Message.obtain();
11843            msg.what = SHOW_ERROR_MSG;
11844            HashMap data = new HashMap();
11845            data.put("result", result);
11846            data.put("app", r);
11847            msg.obj = data;
11848            mHandler.sendMessage(msg);
11849
11850            Binder.restoreCallingIdentity(origId);
11851        }
11852
11853        int res = result.get();
11854
11855        Intent appErrorIntent = null;
11856        synchronized (this) {
11857            if (r != null && !r.isolated) {
11858                // XXX Can't keep track of crash time for isolated processes,
11859                // since they don't have a persistent identity.
11860                mProcessCrashTimes.put(r.info.processName, r.uid,
11861                        SystemClock.uptimeMillis());
11862            }
11863            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11864                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11865            }
11866        }
11867
11868        if (appErrorIntent != null) {
11869            try {
11870                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11871            } catch (ActivityNotFoundException e) {
11872                Slog.w(TAG, "bug report receiver dissappeared", e);
11873            }
11874        }
11875    }
11876
11877    Intent createAppErrorIntentLocked(ProcessRecord r,
11878            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11879        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11880        if (report == null) {
11881            return null;
11882        }
11883        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11884        result.setComponent(r.errorReportReceiver);
11885        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11886        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11887        return result;
11888    }
11889
11890    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11891            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11892        if (r.errorReportReceiver == null) {
11893            return null;
11894        }
11895
11896        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11897            return null;
11898        }
11899
11900        ApplicationErrorReport report = new ApplicationErrorReport();
11901        report.packageName = r.info.packageName;
11902        report.installerPackageName = r.errorReportReceiver.getPackageName();
11903        report.processName = r.processName;
11904        report.time = timeMillis;
11905        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11906
11907        if (r.crashing || r.forceCrashReport) {
11908            report.type = ApplicationErrorReport.TYPE_CRASH;
11909            report.crashInfo = crashInfo;
11910        } else if (r.notResponding) {
11911            report.type = ApplicationErrorReport.TYPE_ANR;
11912            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11913
11914            report.anrInfo.activity = r.notRespondingReport.tag;
11915            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11916            report.anrInfo.info = r.notRespondingReport.longMsg;
11917        }
11918
11919        return report;
11920    }
11921
11922    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11923        enforceNotIsolatedCaller("getProcessesInErrorState");
11924        // assume our apps are happy - lazy create the list
11925        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11926
11927        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11928                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11929        int userId = UserHandle.getUserId(Binder.getCallingUid());
11930
11931        synchronized (this) {
11932
11933            // iterate across all processes
11934            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11935                ProcessRecord app = mLruProcesses.get(i);
11936                if (!allUsers && app.userId != userId) {
11937                    continue;
11938                }
11939                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11940                    // This one's in trouble, so we'll generate a report for it
11941                    // crashes are higher priority (in case there's a crash *and* an anr)
11942                    ActivityManager.ProcessErrorStateInfo report = null;
11943                    if (app.crashing) {
11944                        report = app.crashingReport;
11945                    } else if (app.notResponding) {
11946                        report = app.notRespondingReport;
11947                    }
11948
11949                    if (report != null) {
11950                        if (errList == null) {
11951                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11952                        }
11953                        errList.add(report);
11954                    } else {
11955                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11956                                " crashing = " + app.crashing +
11957                                " notResponding = " + app.notResponding);
11958                    }
11959                }
11960            }
11961        }
11962
11963        return errList;
11964    }
11965
11966    static int procStateToImportance(int procState, int memAdj,
11967            ActivityManager.RunningAppProcessInfo currApp) {
11968        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11969        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11970            currApp.lru = memAdj;
11971        } else {
11972            currApp.lru = 0;
11973        }
11974        return imp;
11975    }
11976
11977    private void fillInProcMemInfo(ProcessRecord app,
11978            ActivityManager.RunningAppProcessInfo outInfo) {
11979        outInfo.pid = app.pid;
11980        outInfo.uid = app.info.uid;
11981        if (mHeavyWeightProcess == app) {
11982            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11983        }
11984        if (app.persistent) {
11985            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11986        }
11987        if (app.activities.size() > 0) {
11988            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11989        }
11990        outInfo.lastTrimLevel = app.trimMemoryLevel;
11991        int adj = app.curAdj;
11992        int procState = app.curProcState;
11993        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11994        outInfo.importanceReasonCode = app.adjTypeCode;
11995        outInfo.processState = app.curProcState;
11996    }
11997
11998    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11999        enforceNotIsolatedCaller("getRunningAppProcesses");
12000        // Lazy instantiation of list
12001        List<ActivityManager.RunningAppProcessInfo> runList = null;
12002        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12003                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12004        int userId = UserHandle.getUserId(Binder.getCallingUid());
12005        synchronized (this) {
12006            // Iterate across all processes
12007            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12008                ProcessRecord app = mLruProcesses.get(i);
12009                if (!allUsers && app.userId != userId) {
12010                    continue;
12011                }
12012                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12013                    // Generate process state info for running application
12014                    ActivityManager.RunningAppProcessInfo currApp =
12015                        new ActivityManager.RunningAppProcessInfo(app.processName,
12016                                app.pid, app.getPackageList());
12017                    fillInProcMemInfo(app, currApp);
12018                    if (app.adjSource instanceof ProcessRecord) {
12019                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12020                        currApp.importanceReasonImportance =
12021                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12022                                        app.adjSourceProcState);
12023                    } else if (app.adjSource instanceof ActivityRecord) {
12024                        ActivityRecord r = (ActivityRecord)app.adjSource;
12025                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12026                    }
12027                    if (app.adjTarget instanceof ComponentName) {
12028                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12029                    }
12030                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12031                    //        + " lru=" + currApp.lru);
12032                    if (runList == null) {
12033                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12034                    }
12035                    runList.add(currApp);
12036                }
12037            }
12038        }
12039        return runList;
12040    }
12041
12042    public List<ApplicationInfo> getRunningExternalApplications() {
12043        enforceNotIsolatedCaller("getRunningExternalApplications");
12044        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12045        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12046        if (runningApps != null && runningApps.size() > 0) {
12047            Set<String> extList = new HashSet<String>();
12048            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12049                if (app.pkgList != null) {
12050                    for (String pkg : app.pkgList) {
12051                        extList.add(pkg);
12052                    }
12053                }
12054            }
12055            IPackageManager pm = AppGlobals.getPackageManager();
12056            for (String pkg : extList) {
12057                try {
12058                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12059                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12060                        retList.add(info);
12061                    }
12062                } catch (RemoteException e) {
12063                }
12064            }
12065        }
12066        return retList;
12067    }
12068
12069    @Override
12070    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12071        enforceNotIsolatedCaller("getMyMemoryState");
12072        synchronized (this) {
12073            ProcessRecord proc;
12074            synchronized (mPidsSelfLocked) {
12075                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12076            }
12077            fillInProcMemInfo(proc, outInfo);
12078        }
12079    }
12080
12081    @Override
12082    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12083        if (checkCallingPermission(android.Manifest.permission.DUMP)
12084                != PackageManager.PERMISSION_GRANTED) {
12085            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12086                    + Binder.getCallingPid()
12087                    + ", uid=" + Binder.getCallingUid()
12088                    + " without permission "
12089                    + android.Manifest.permission.DUMP);
12090            return;
12091        }
12092
12093        boolean dumpAll = false;
12094        boolean dumpClient = false;
12095        String dumpPackage = null;
12096
12097        int opti = 0;
12098        while (opti < args.length) {
12099            String opt = args[opti];
12100            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12101                break;
12102            }
12103            opti++;
12104            if ("-a".equals(opt)) {
12105                dumpAll = true;
12106            } else if ("-c".equals(opt)) {
12107                dumpClient = true;
12108            } else if ("-p".equals(opt)) {
12109                if (opti < args.length) {
12110                    dumpPackage = args[opti];
12111                    opti++;
12112                } else {
12113                    pw.println("Error: -p option requires package argument");
12114                    return;
12115                }
12116                dumpClient = true;
12117            } else if ("-h".equals(opt)) {
12118                pw.println("Activity manager dump options:");
12119                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12120                pw.println("  cmd may be one of:");
12121                pw.println("    a[ctivities]: activity stack state");
12122                pw.println("    r[recents]: recent activities state");
12123                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12124                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12125                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12126                pw.println("    o[om]: out of memory management");
12127                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12128                pw.println("    provider [COMP_SPEC]: provider client-side state");
12129                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12130                pw.println("    as[sociations]: tracked app associations");
12131                pw.println("    service [COMP_SPEC]: service client-side state");
12132                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12133                pw.println("    all: dump all activities");
12134                pw.println("    top: dump the top activity");
12135                pw.println("    write: write all pending state to storage");
12136                pw.println("    track-associations: enable association tracking");
12137                pw.println("    untrack-associations: disable and clear association tracking");
12138                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12139                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12140                pw.println("    a partial substring in a component name, a");
12141                pw.println("    hex object identifier.");
12142                pw.println("  -a: include all available server state.");
12143                pw.println("  -c: include client state.");
12144                pw.println("  -p: limit output to given package.");
12145                return;
12146            } else {
12147                pw.println("Unknown argument: " + opt + "; use -h for help");
12148            }
12149        }
12150
12151        long origId = Binder.clearCallingIdentity();
12152        boolean more = false;
12153        // Is the caller requesting to dump a particular piece of data?
12154        if (opti < args.length) {
12155            String cmd = args[opti];
12156            opti++;
12157            if ("activities".equals(cmd) || "a".equals(cmd)) {
12158                synchronized (this) {
12159                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12160                }
12161            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12162                synchronized (this) {
12163                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12164                }
12165            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12166                String[] newArgs;
12167                String name;
12168                if (opti >= args.length) {
12169                    name = null;
12170                    newArgs = EMPTY_STRING_ARRAY;
12171                } else {
12172                    dumpPackage = args[opti];
12173                    opti++;
12174                    newArgs = new String[args.length - opti];
12175                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12176                            args.length - opti);
12177                }
12178                synchronized (this) {
12179                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12180                }
12181            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12182                String[] newArgs;
12183                String name;
12184                if (opti >= args.length) {
12185                    name = null;
12186                    newArgs = EMPTY_STRING_ARRAY;
12187                } else {
12188                    dumpPackage = args[opti];
12189                    opti++;
12190                    newArgs = new String[args.length - opti];
12191                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12192                            args.length - opti);
12193                }
12194                synchronized (this) {
12195                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12196                }
12197            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12198                String[] newArgs;
12199                String name;
12200                if (opti >= args.length) {
12201                    name = null;
12202                    newArgs = EMPTY_STRING_ARRAY;
12203                } else {
12204                    dumpPackage = args[opti];
12205                    opti++;
12206                    newArgs = new String[args.length - opti];
12207                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12208                            args.length - opti);
12209                }
12210                synchronized (this) {
12211                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12212                }
12213            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12214                synchronized (this) {
12215                    dumpOomLocked(fd, pw, args, opti, true);
12216                }
12217            } else if ("provider".equals(cmd)) {
12218                String[] newArgs;
12219                String name;
12220                if (opti >= args.length) {
12221                    name = null;
12222                    newArgs = EMPTY_STRING_ARRAY;
12223                } else {
12224                    name = args[opti];
12225                    opti++;
12226                    newArgs = new String[args.length - opti];
12227                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12228                }
12229                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12230                    pw.println("No providers match: " + name);
12231                    pw.println("Use -h for help.");
12232                }
12233            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12234                synchronized (this) {
12235                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12236                }
12237            } else if ("service".equals(cmd)) {
12238                String[] newArgs;
12239                String name;
12240                if (opti >= args.length) {
12241                    name = null;
12242                    newArgs = EMPTY_STRING_ARRAY;
12243                } else {
12244                    name = args[opti];
12245                    opti++;
12246                    newArgs = new String[args.length - opti];
12247                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12248                            args.length - opti);
12249                }
12250                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12251                    pw.println("No services match: " + name);
12252                    pw.println("Use -h for help.");
12253                }
12254            } else if ("package".equals(cmd)) {
12255                String[] newArgs;
12256                if (opti >= args.length) {
12257                    pw.println("package: no package name specified");
12258                    pw.println("Use -h for help.");
12259                } else {
12260                    dumpPackage = args[opti];
12261                    opti++;
12262                    newArgs = new String[args.length - opti];
12263                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12264                            args.length - opti);
12265                    args = newArgs;
12266                    opti = 0;
12267                    more = true;
12268                }
12269            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12270                synchronized (this) {
12271                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12272                }
12273            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12274                synchronized (this) {
12275                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12276                }
12277            } else if ("write".equals(cmd)) {
12278                mTaskPersister.flush();
12279                pw.println("All tasks persisted.");
12280                return;
12281            } else if ("track-associations".equals(cmd)) {
12282                synchronized (this) {
12283                    if (!mTrackingAssociations) {
12284                        mTrackingAssociations = true;
12285                        pw.println("Association tracking started.");
12286                    } else {
12287                        pw.println("Association tracking already enabled.");
12288                    }
12289                }
12290                return;
12291            } else if ("untrack-associations".equals(cmd)) {
12292                synchronized (this) {
12293                    if (mTrackingAssociations) {
12294                        mTrackingAssociations = false;
12295                        mAssociations.clear();
12296                        pw.println("Association tracking stopped.");
12297                    } else {
12298                        pw.println("Association tracking not running.");
12299                    }
12300                }
12301                return;
12302            } else {
12303                // Dumping a single activity?
12304                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12305                    pw.println("Bad activity command, or no activities match: " + cmd);
12306                    pw.println("Use -h for help.");
12307                }
12308            }
12309            if (!more) {
12310                Binder.restoreCallingIdentity(origId);
12311                return;
12312            }
12313        }
12314
12315        // No piece of data specified, dump everything.
12316        synchronized (this) {
12317            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12318            pw.println();
12319            if (dumpAll) {
12320                pw.println("-------------------------------------------------------------------------------");
12321            }
12322            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12323            pw.println();
12324            if (dumpAll) {
12325                pw.println("-------------------------------------------------------------------------------");
12326            }
12327            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12328            pw.println();
12329            if (dumpAll) {
12330                pw.println("-------------------------------------------------------------------------------");
12331            }
12332            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12333            pw.println();
12334            if (dumpAll) {
12335                pw.println("-------------------------------------------------------------------------------");
12336            }
12337            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12338            pw.println();
12339            if (dumpAll) {
12340                pw.println("-------------------------------------------------------------------------------");
12341            }
12342            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12343            if (mAssociations.size() > 0) {
12344                pw.println();
12345                if (dumpAll) {
12346                    pw.println("-------------------------------------------------------------------------------");
12347                }
12348                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12349            }
12350            pw.println();
12351            if (dumpAll) {
12352                pw.println("-------------------------------------------------------------------------------");
12353            }
12354            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12355        }
12356        Binder.restoreCallingIdentity(origId);
12357    }
12358
12359    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12360            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12361        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12362
12363        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12364                dumpPackage);
12365        boolean needSep = printedAnything;
12366
12367        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12368                dumpPackage, needSep, "  mFocusedActivity: ");
12369        if (printed) {
12370            printedAnything = true;
12371            needSep = false;
12372        }
12373
12374        if (dumpPackage == null) {
12375            if (needSep) {
12376                pw.println();
12377            }
12378            needSep = true;
12379            printedAnything = true;
12380            mStackSupervisor.dump(pw, "  ");
12381        }
12382
12383        if (!printedAnything) {
12384            pw.println("  (nothing)");
12385        }
12386    }
12387
12388    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12389            int opti, boolean dumpAll, String dumpPackage) {
12390        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12391
12392        boolean printedAnything = false;
12393
12394        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12395            boolean printedHeader = false;
12396
12397            final int N = mRecentTasks.size();
12398            for (int i=0; i<N; i++) {
12399                TaskRecord tr = mRecentTasks.get(i);
12400                if (dumpPackage != null) {
12401                    if (tr.realActivity == null ||
12402                            !dumpPackage.equals(tr.realActivity)) {
12403                        continue;
12404                    }
12405                }
12406                if (!printedHeader) {
12407                    pw.println("  Recent tasks:");
12408                    printedHeader = true;
12409                    printedAnything = true;
12410                }
12411                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12412                        pw.println(tr);
12413                if (dumpAll) {
12414                    mRecentTasks.get(i).dump(pw, "    ");
12415                }
12416            }
12417        }
12418
12419        if (!printedAnything) {
12420            pw.println("  (nothing)");
12421        }
12422    }
12423
12424    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12425            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12426        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12427
12428        int dumpUid = 0;
12429        if (dumpPackage != null) {
12430            IPackageManager pm = AppGlobals.getPackageManager();
12431            try {
12432                dumpUid = pm.getPackageUid(dumpPackage, 0);
12433            } catch (RemoteException e) {
12434            }
12435        }
12436
12437        boolean printedAnything = false;
12438
12439        final long now = SystemClock.uptimeMillis();
12440
12441        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12442            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12443                    = mAssociations.valueAt(i1);
12444            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12445                SparseArray<ArrayMap<String, Association>> sourceUids
12446                        = targetComponents.valueAt(i2);
12447                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12448                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12449                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12450                        Association ass = sourceProcesses.valueAt(i4);
12451                        if (dumpPackage != null) {
12452                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12453                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12454                                continue;
12455                            }
12456                        }
12457                        printedAnything = true;
12458                        pw.print("  ");
12459                        pw.print(ass.mTargetProcess);
12460                        pw.print("/");
12461                        UserHandle.formatUid(pw, ass.mTargetUid);
12462                        pw.print(" <- ");
12463                        pw.print(ass.mSourceProcess);
12464                        pw.print("/");
12465                        UserHandle.formatUid(pw, ass.mSourceUid);
12466                        pw.println();
12467                        pw.print("    via ");
12468                        pw.print(ass.mTargetComponent.flattenToShortString());
12469                        pw.println();
12470                        pw.print("    ");
12471                        long dur = ass.mTime;
12472                        if (ass.mNesting > 0) {
12473                            dur += now - ass.mStartTime;
12474                        }
12475                        TimeUtils.formatDuration(dur, pw);
12476                        pw.print(" (");
12477                        pw.print(ass.mCount);
12478                        pw.println(" times)");
12479                        if (ass.mNesting > 0) {
12480                            pw.print("    ");
12481                            pw.print(" Currently active: ");
12482                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12483                            pw.println();
12484                        }
12485                    }
12486                }
12487            }
12488
12489        }
12490
12491        if (!printedAnything) {
12492            pw.println("  (nothing)");
12493        }
12494    }
12495
12496    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12497            int opti, boolean dumpAll, String dumpPackage) {
12498        boolean needSep = false;
12499        boolean printedAnything = false;
12500        int numPers = 0;
12501
12502        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12503
12504        if (dumpAll) {
12505            final int NP = mProcessNames.getMap().size();
12506            for (int ip=0; ip<NP; ip++) {
12507                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12508                final int NA = procs.size();
12509                for (int ia=0; ia<NA; ia++) {
12510                    ProcessRecord r = procs.valueAt(ia);
12511                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12512                        continue;
12513                    }
12514                    if (!needSep) {
12515                        pw.println("  All known processes:");
12516                        needSep = true;
12517                        printedAnything = true;
12518                    }
12519                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12520                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12521                        pw.print(" "); pw.println(r);
12522                    r.dump(pw, "    ");
12523                    if (r.persistent) {
12524                        numPers++;
12525                    }
12526                }
12527            }
12528        }
12529
12530        if (mIsolatedProcesses.size() > 0) {
12531            boolean printed = false;
12532            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12533                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12534                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12535                    continue;
12536                }
12537                if (!printed) {
12538                    if (needSep) {
12539                        pw.println();
12540                    }
12541                    pw.println("  Isolated process list (sorted by uid):");
12542                    printedAnything = true;
12543                    printed = true;
12544                    needSep = true;
12545                }
12546                pw.println(String.format("%sIsolated #%2d: %s",
12547                        "    ", i, r.toString()));
12548            }
12549        }
12550
12551        if (mLruProcesses.size() > 0) {
12552            if (needSep) {
12553                pw.println();
12554            }
12555            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12556                    pw.print(" total, non-act at ");
12557                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12558                    pw.print(", non-svc at ");
12559                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12560                    pw.println("):");
12561            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12562            needSep = true;
12563            printedAnything = true;
12564        }
12565
12566        if (dumpAll || dumpPackage != null) {
12567            synchronized (mPidsSelfLocked) {
12568                boolean printed = false;
12569                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12570                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12571                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12572                        continue;
12573                    }
12574                    if (!printed) {
12575                        if (needSep) pw.println();
12576                        needSep = true;
12577                        pw.println("  PID mappings:");
12578                        printed = true;
12579                        printedAnything = true;
12580                    }
12581                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12582                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12583                }
12584            }
12585        }
12586
12587        if (mForegroundProcesses.size() > 0) {
12588            synchronized (mPidsSelfLocked) {
12589                boolean printed = false;
12590                for (int i=0; i<mForegroundProcesses.size(); i++) {
12591                    ProcessRecord r = mPidsSelfLocked.get(
12592                            mForegroundProcesses.valueAt(i).pid);
12593                    if (dumpPackage != null && (r == null
12594                            || !r.pkgList.containsKey(dumpPackage))) {
12595                        continue;
12596                    }
12597                    if (!printed) {
12598                        if (needSep) pw.println();
12599                        needSep = true;
12600                        pw.println("  Foreground Processes:");
12601                        printed = true;
12602                        printedAnything = true;
12603                    }
12604                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12605                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12606                }
12607            }
12608        }
12609
12610        if (mPersistentStartingProcesses.size() > 0) {
12611            if (needSep) pw.println();
12612            needSep = true;
12613            printedAnything = true;
12614            pw.println("  Persisent processes that are starting:");
12615            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12616                    "Starting Norm", "Restarting PERS", dumpPackage);
12617        }
12618
12619        if (mRemovedProcesses.size() > 0) {
12620            if (needSep) pw.println();
12621            needSep = true;
12622            printedAnything = true;
12623            pw.println("  Processes that are being removed:");
12624            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12625                    "Removed Norm", "Removed PERS", dumpPackage);
12626        }
12627
12628        if (mProcessesOnHold.size() > 0) {
12629            if (needSep) pw.println();
12630            needSep = true;
12631            printedAnything = true;
12632            pw.println("  Processes that are on old until the system is ready:");
12633            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12634                    "OnHold Norm", "OnHold PERS", dumpPackage);
12635        }
12636
12637        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12638
12639        if (mProcessCrashTimes.getMap().size() > 0) {
12640            boolean printed = false;
12641            long now = SystemClock.uptimeMillis();
12642            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12643            final int NP = pmap.size();
12644            for (int ip=0; ip<NP; ip++) {
12645                String pname = pmap.keyAt(ip);
12646                SparseArray<Long> uids = pmap.valueAt(ip);
12647                final int N = uids.size();
12648                for (int i=0; i<N; i++) {
12649                    int puid = uids.keyAt(i);
12650                    ProcessRecord r = mProcessNames.get(pname, puid);
12651                    if (dumpPackage != null && (r == null
12652                            || !r.pkgList.containsKey(dumpPackage))) {
12653                        continue;
12654                    }
12655                    if (!printed) {
12656                        if (needSep) pw.println();
12657                        needSep = true;
12658                        pw.println("  Time since processes crashed:");
12659                        printed = true;
12660                        printedAnything = true;
12661                    }
12662                    pw.print("    Process "); pw.print(pname);
12663                            pw.print(" uid "); pw.print(puid);
12664                            pw.print(": last crashed ");
12665                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12666                            pw.println(" ago");
12667                }
12668            }
12669        }
12670
12671        if (mBadProcesses.getMap().size() > 0) {
12672            boolean printed = false;
12673            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12674            final int NP = pmap.size();
12675            for (int ip=0; ip<NP; ip++) {
12676                String pname = pmap.keyAt(ip);
12677                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12678                final int N = uids.size();
12679                for (int i=0; i<N; i++) {
12680                    int puid = uids.keyAt(i);
12681                    ProcessRecord r = mProcessNames.get(pname, puid);
12682                    if (dumpPackage != null && (r == null
12683                            || !r.pkgList.containsKey(dumpPackage))) {
12684                        continue;
12685                    }
12686                    if (!printed) {
12687                        if (needSep) pw.println();
12688                        needSep = true;
12689                        pw.println("  Bad processes:");
12690                        printedAnything = true;
12691                    }
12692                    BadProcessInfo info = uids.valueAt(i);
12693                    pw.print("    Bad process "); pw.print(pname);
12694                            pw.print(" uid "); pw.print(puid);
12695                            pw.print(": crashed at time "); pw.println(info.time);
12696                    if (info.shortMsg != null) {
12697                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12698                    }
12699                    if (info.longMsg != null) {
12700                        pw.print("      Long msg: "); pw.println(info.longMsg);
12701                    }
12702                    if (info.stack != null) {
12703                        pw.println("      Stack:");
12704                        int lastPos = 0;
12705                        for (int pos=0; pos<info.stack.length(); pos++) {
12706                            if (info.stack.charAt(pos) == '\n') {
12707                                pw.print("        ");
12708                                pw.write(info.stack, lastPos, pos-lastPos);
12709                                pw.println();
12710                                lastPos = pos+1;
12711                            }
12712                        }
12713                        if (lastPos < info.stack.length()) {
12714                            pw.print("        ");
12715                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12716                            pw.println();
12717                        }
12718                    }
12719                }
12720            }
12721        }
12722
12723        if (dumpPackage == null) {
12724            pw.println();
12725            needSep = false;
12726            pw.println("  mStartedUsers:");
12727            for (int i=0; i<mStartedUsers.size(); i++) {
12728                UserStartedState uss = mStartedUsers.valueAt(i);
12729                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12730                        pw.print(": "); uss.dump("", pw);
12731            }
12732            pw.print("  mStartedUserArray: [");
12733            for (int i=0; i<mStartedUserArray.length; i++) {
12734                if (i > 0) pw.print(", ");
12735                pw.print(mStartedUserArray[i]);
12736            }
12737            pw.println("]");
12738            pw.print("  mUserLru: [");
12739            for (int i=0; i<mUserLru.size(); i++) {
12740                if (i > 0) pw.print(", ");
12741                pw.print(mUserLru.get(i));
12742            }
12743            pw.println("]");
12744            if (dumpAll) {
12745                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12746            }
12747            synchronized (mUserProfileGroupIdsSelfLocked) {
12748                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12749                    pw.println("  mUserProfileGroupIds:");
12750                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12751                        pw.print("    User #");
12752                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12753                        pw.print(" -> profile #");
12754                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12755                    }
12756                }
12757            }
12758        }
12759        if (mHomeProcess != null && (dumpPackage == null
12760                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12761            if (needSep) {
12762                pw.println();
12763                needSep = false;
12764            }
12765            pw.println("  mHomeProcess: " + mHomeProcess);
12766        }
12767        if (mPreviousProcess != null && (dumpPackage == null
12768                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12769            if (needSep) {
12770                pw.println();
12771                needSep = false;
12772            }
12773            pw.println("  mPreviousProcess: " + mPreviousProcess);
12774        }
12775        if (dumpAll) {
12776            StringBuilder sb = new StringBuilder(128);
12777            sb.append("  mPreviousProcessVisibleTime: ");
12778            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12779            pw.println(sb);
12780        }
12781        if (mHeavyWeightProcess != null && (dumpPackage == null
12782                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12783            if (needSep) {
12784                pw.println();
12785                needSep = false;
12786            }
12787            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12788        }
12789        if (dumpPackage == null) {
12790            pw.println("  mConfiguration: " + mConfiguration);
12791        }
12792        if (dumpAll) {
12793            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12794            if (mCompatModePackages.getPackages().size() > 0) {
12795                boolean printed = false;
12796                for (Map.Entry<String, Integer> entry
12797                        : mCompatModePackages.getPackages().entrySet()) {
12798                    String pkg = entry.getKey();
12799                    int mode = entry.getValue();
12800                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12801                        continue;
12802                    }
12803                    if (!printed) {
12804                        pw.println("  mScreenCompatPackages:");
12805                        printed = true;
12806                    }
12807                    pw.print("    "); pw.print(pkg); pw.print(": ");
12808                            pw.print(mode); pw.println();
12809                }
12810            }
12811        }
12812        if (dumpPackage == null) {
12813            pw.println("  mWakefulness="
12814                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12815            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12816                    + lockScreenShownToString());
12817            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12818                    + " mTestPssMode=" + mTestPssMode);
12819        }
12820        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12821                || mOrigWaitForDebugger) {
12822            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12823                    || dumpPackage.equals(mOrigDebugApp)) {
12824                if (needSep) {
12825                    pw.println();
12826                    needSep = false;
12827                }
12828                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12829                        + " mDebugTransient=" + mDebugTransient
12830                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12831            }
12832        }
12833        if (mMemWatchProcesses.size() > 0) {
12834            pw.println("  Mem watch processes:");
12835            for (int i=0; i<mMemWatchProcesses.size(); i++) {
12836                if (needSep) {
12837                    pw.println();
12838                    needSep = false;
12839                }
12840                pw.print("    "); pw.print(mMemWatchProcesses.keyAt(i));
12841                pw.print(": "); DebugUtils.printSizeValue(pw, mMemWatchProcesses.valueAt(i));
12842                pw.println();
12843            }
12844            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
12845            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
12846            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
12847                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
12848        }
12849        if (mOpenGlTraceApp != null) {
12850            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12851                if (needSep) {
12852                    pw.println();
12853                    needSep = false;
12854                }
12855                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12856            }
12857        }
12858        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12859                || mProfileFd != null) {
12860            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12861                if (needSep) {
12862                    pw.println();
12863                    needSep = false;
12864                }
12865                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12866                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12867                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12868                        + mAutoStopProfiler);
12869                pw.println("  mProfileType=" + mProfileType);
12870            }
12871        }
12872        if (dumpPackage == null) {
12873            if (mAlwaysFinishActivities || mController != null) {
12874                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12875                        + " mController=" + mController);
12876            }
12877            if (dumpAll) {
12878                pw.println("  Total persistent processes: " + numPers);
12879                pw.println("  mProcessesReady=" + mProcessesReady
12880                        + " mSystemReady=" + mSystemReady
12881                        + " mBooted=" + mBooted
12882                        + " mFactoryTest=" + mFactoryTest);
12883                pw.println("  mBooting=" + mBooting
12884                        + " mCallFinishBooting=" + mCallFinishBooting
12885                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12886                pw.print("  mLastPowerCheckRealtime=");
12887                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12888                        pw.println("");
12889                pw.print("  mLastPowerCheckUptime=");
12890                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12891                        pw.println("");
12892                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12893                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12894                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12895                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12896                        + " (" + mLruProcesses.size() + " total)"
12897                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12898                        + " mNumServiceProcs=" + mNumServiceProcs
12899                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12900                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12901                        + " mLastMemoryLevel" + mLastMemoryLevel
12902                        + " mLastNumProcesses" + mLastNumProcesses);
12903                long now = SystemClock.uptimeMillis();
12904                pw.print("  mLastIdleTime=");
12905                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12906                        pw.print(" mLowRamSinceLastIdle=");
12907                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12908                        pw.println();
12909            }
12910        }
12911
12912        if (!printedAnything) {
12913            pw.println("  (nothing)");
12914        }
12915    }
12916
12917    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12918            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12919        if (mProcessesToGc.size() > 0) {
12920            boolean printed = false;
12921            long now = SystemClock.uptimeMillis();
12922            for (int i=0; i<mProcessesToGc.size(); i++) {
12923                ProcessRecord proc = mProcessesToGc.get(i);
12924                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12925                    continue;
12926                }
12927                if (!printed) {
12928                    if (needSep) pw.println();
12929                    needSep = true;
12930                    pw.println("  Processes that are waiting to GC:");
12931                    printed = true;
12932                }
12933                pw.print("    Process "); pw.println(proc);
12934                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12935                        pw.print(", last gced=");
12936                        pw.print(now-proc.lastRequestedGc);
12937                        pw.print(" ms ago, last lowMem=");
12938                        pw.print(now-proc.lastLowMemory);
12939                        pw.println(" ms ago");
12940
12941            }
12942        }
12943        return needSep;
12944    }
12945
12946    void printOomLevel(PrintWriter pw, String name, int adj) {
12947        pw.print("    ");
12948        if (adj >= 0) {
12949            pw.print(' ');
12950            if (adj < 10) pw.print(' ');
12951        } else {
12952            if (adj > -10) pw.print(' ');
12953        }
12954        pw.print(adj);
12955        pw.print(": ");
12956        pw.print(name);
12957        pw.print(" (");
12958        pw.print(mProcessList.getMemLevel(adj)/1024);
12959        pw.println(" kB)");
12960    }
12961
12962    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12963            int opti, boolean dumpAll) {
12964        boolean needSep = false;
12965
12966        if (mLruProcesses.size() > 0) {
12967            if (needSep) pw.println();
12968            needSep = true;
12969            pw.println("  OOM levels:");
12970            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12971            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12972            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12973            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12974            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12975            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12976            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12977            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12978            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12979            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12980            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12981            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12982            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12983            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12984
12985            if (needSep) pw.println();
12986            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12987                    pw.print(" total, non-act at ");
12988                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12989                    pw.print(", non-svc at ");
12990                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12991                    pw.println("):");
12992            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12993            needSep = true;
12994        }
12995
12996        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12997
12998        pw.println();
12999        pw.println("  mHomeProcess: " + mHomeProcess);
13000        pw.println("  mPreviousProcess: " + mPreviousProcess);
13001        if (mHeavyWeightProcess != null) {
13002            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13003        }
13004
13005        return true;
13006    }
13007
13008    /**
13009     * There are three ways to call this:
13010     *  - no provider specified: dump all the providers
13011     *  - a flattened component name that matched an existing provider was specified as the
13012     *    first arg: dump that one provider
13013     *  - the first arg isn't the flattened component name of an existing provider:
13014     *    dump all providers whose component contains the first arg as a substring
13015     */
13016    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13017            int opti, boolean dumpAll) {
13018        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13019    }
13020
13021    static class ItemMatcher {
13022        ArrayList<ComponentName> components;
13023        ArrayList<String> strings;
13024        ArrayList<Integer> objects;
13025        boolean all;
13026
13027        ItemMatcher() {
13028            all = true;
13029        }
13030
13031        void build(String name) {
13032            ComponentName componentName = ComponentName.unflattenFromString(name);
13033            if (componentName != null) {
13034                if (components == null) {
13035                    components = new ArrayList<ComponentName>();
13036                }
13037                components.add(componentName);
13038                all = false;
13039            } else {
13040                int objectId = 0;
13041                // Not a '/' separated full component name; maybe an object ID?
13042                try {
13043                    objectId = Integer.parseInt(name, 16);
13044                    if (objects == null) {
13045                        objects = new ArrayList<Integer>();
13046                    }
13047                    objects.add(objectId);
13048                    all = false;
13049                } catch (RuntimeException e) {
13050                    // Not an integer; just do string match.
13051                    if (strings == null) {
13052                        strings = new ArrayList<String>();
13053                    }
13054                    strings.add(name);
13055                    all = false;
13056                }
13057            }
13058        }
13059
13060        int build(String[] args, int opti) {
13061            for (; opti<args.length; opti++) {
13062                String name = args[opti];
13063                if ("--".equals(name)) {
13064                    return opti+1;
13065                }
13066                build(name);
13067            }
13068            return opti;
13069        }
13070
13071        boolean match(Object object, ComponentName comp) {
13072            if (all) {
13073                return true;
13074            }
13075            if (components != null) {
13076                for (int i=0; i<components.size(); i++) {
13077                    if (components.get(i).equals(comp)) {
13078                        return true;
13079                    }
13080                }
13081            }
13082            if (objects != null) {
13083                for (int i=0; i<objects.size(); i++) {
13084                    if (System.identityHashCode(object) == objects.get(i)) {
13085                        return true;
13086                    }
13087                }
13088            }
13089            if (strings != null) {
13090                String flat = comp.flattenToString();
13091                for (int i=0; i<strings.size(); i++) {
13092                    if (flat.contains(strings.get(i))) {
13093                        return true;
13094                    }
13095                }
13096            }
13097            return false;
13098        }
13099    }
13100
13101    /**
13102     * There are three things that cmd can be:
13103     *  - a flattened component name that matches an existing activity
13104     *  - the cmd arg isn't the flattened component name of an existing activity:
13105     *    dump all activity whose component contains the cmd as a substring
13106     *  - A hex number of the ActivityRecord object instance.
13107     */
13108    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13109            int opti, boolean dumpAll) {
13110        ArrayList<ActivityRecord> activities;
13111
13112        synchronized (this) {
13113            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13114        }
13115
13116        if (activities.size() <= 0) {
13117            return false;
13118        }
13119
13120        String[] newArgs = new String[args.length - opti];
13121        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13122
13123        TaskRecord lastTask = null;
13124        boolean needSep = false;
13125        for (int i=activities.size()-1; i>=0; i--) {
13126            ActivityRecord r = activities.get(i);
13127            if (needSep) {
13128                pw.println();
13129            }
13130            needSep = true;
13131            synchronized (this) {
13132                if (lastTask != r.task) {
13133                    lastTask = r.task;
13134                    pw.print("TASK "); pw.print(lastTask.affinity);
13135                            pw.print(" id="); pw.println(lastTask.taskId);
13136                    if (dumpAll) {
13137                        lastTask.dump(pw, "  ");
13138                    }
13139                }
13140            }
13141            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13142        }
13143        return true;
13144    }
13145
13146    /**
13147     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13148     * there is a thread associated with the activity.
13149     */
13150    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13151            final ActivityRecord r, String[] args, boolean dumpAll) {
13152        String innerPrefix = prefix + "  ";
13153        synchronized (this) {
13154            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13155                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13156                    pw.print(" pid=");
13157                    if (r.app != null) pw.println(r.app.pid);
13158                    else pw.println("(not running)");
13159            if (dumpAll) {
13160                r.dump(pw, innerPrefix);
13161            }
13162        }
13163        if (r.app != null && r.app.thread != null) {
13164            // flush anything that is already in the PrintWriter since the thread is going
13165            // to write to the file descriptor directly
13166            pw.flush();
13167            try {
13168                TransferPipe tp = new TransferPipe();
13169                try {
13170                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13171                            r.appToken, innerPrefix, args);
13172                    tp.go(fd);
13173                } finally {
13174                    tp.kill();
13175                }
13176            } catch (IOException e) {
13177                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13178            } catch (RemoteException e) {
13179                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13180            }
13181        }
13182    }
13183
13184    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13185            int opti, boolean dumpAll, String dumpPackage) {
13186        boolean needSep = false;
13187        boolean onlyHistory = false;
13188        boolean printedAnything = false;
13189
13190        if ("history".equals(dumpPackage)) {
13191            if (opti < args.length && "-s".equals(args[opti])) {
13192                dumpAll = false;
13193            }
13194            onlyHistory = true;
13195            dumpPackage = null;
13196        }
13197
13198        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13199        if (!onlyHistory && dumpAll) {
13200            if (mRegisteredReceivers.size() > 0) {
13201                boolean printed = false;
13202                Iterator it = mRegisteredReceivers.values().iterator();
13203                while (it.hasNext()) {
13204                    ReceiverList r = (ReceiverList)it.next();
13205                    if (dumpPackage != null && (r.app == null ||
13206                            !dumpPackage.equals(r.app.info.packageName))) {
13207                        continue;
13208                    }
13209                    if (!printed) {
13210                        pw.println("  Registered Receivers:");
13211                        needSep = true;
13212                        printed = true;
13213                        printedAnything = true;
13214                    }
13215                    pw.print("  * "); pw.println(r);
13216                    r.dump(pw, "    ");
13217                }
13218            }
13219
13220            if (mReceiverResolver.dump(pw, needSep ?
13221                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13222                    "    ", dumpPackage, false, false)) {
13223                needSep = true;
13224                printedAnything = true;
13225            }
13226        }
13227
13228        for (BroadcastQueue q : mBroadcastQueues) {
13229            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13230            printedAnything |= needSep;
13231        }
13232
13233        needSep = true;
13234
13235        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13236            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13237                if (needSep) {
13238                    pw.println();
13239                }
13240                needSep = true;
13241                printedAnything = true;
13242                pw.print("  Sticky broadcasts for user ");
13243                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13244                StringBuilder sb = new StringBuilder(128);
13245                for (Map.Entry<String, ArrayList<Intent>> ent
13246                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13247                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13248                    if (dumpAll) {
13249                        pw.println(":");
13250                        ArrayList<Intent> intents = ent.getValue();
13251                        final int N = intents.size();
13252                        for (int i=0; i<N; i++) {
13253                            sb.setLength(0);
13254                            sb.append("    Intent: ");
13255                            intents.get(i).toShortString(sb, false, true, false, false);
13256                            pw.println(sb.toString());
13257                            Bundle bundle = intents.get(i).getExtras();
13258                            if (bundle != null) {
13259                                pw.print("      ");
13260                                pw.println(bundle.toString());
13261                            }
13262                        }
13263                    } else {
13264                        pw.println("");
13265                    }
13266                }
13267            }
13268        }
13269
13270        if (!onlyHistory && dumpAll) {
13271            pw.println();
13272            for (BroadcastQueue queue : mBroadcastQueues) {
13273                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13274                        + queue.mBroadcastsScheduled);
13275            }
13276            pw.println("  mHandler:");
13277            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13278            needSep = true;
13279            printedAnything = true;
13280        }
13281
13282        if (!printedAnything) {
13283            pw.println("  (nothing)");
13284        }
13285    }
13286
13287    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13288            int opti, boolean dumpAll, String dumpPackage) {
13289        boolean needSep;
13290        boolean printedAnything = false;
13291
13292        ItemMatcher matcher = new ItemMatcher();
13293        matcher.build(args, opti);
13294
13295        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13296
13297        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13298        printedAnything |= needSep;
13299
13300        if (mLaunchingProviders.size() > 0) {
13301            boolean printed = false;
13302            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13303                ContentProviderRecord r = mLaunchingProviders.get(i);
13304                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13305                    continue;
13306                }
13307                if (!printed) {
13308                    if (needSep) pw.println();
13309                    needSep = true;
13310                    pw.println("  Launching content providers:");
13311                    printed = true;
13312                    printedAnything = true;
13313                }
13314                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13315                        pw.println(r);
13316            }
13317        }
13318
13319        if (mGrantedUriPermissions.size() > 0) {
13320            boolean printed = false;
13321            int dumpUid = -2;
13322            if (dumpPackage != null) {
13323                try {
13324                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13325                } catch (NameNotFoundException e) {
13326                    dumpUid = -1;
13327                }
13328            }
13329            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13330                int uid = mGrantedUriPermissions.keyAt(i);
13331                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13332                    continue;
13333                }
13334                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13335                if (!printed) {
13336                    if (needSep) pw.println();
13337                    needSep = true;
13338                    pw.println("  Granted Uri Permissions:");
13339                    printed = true;
13340                    printedAnything = true;
13341                }
13342                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13343                for (UriPermission perm : perms.values()) {
13344                    pw.print("    "); pw.println(perm);
13345                    if (dumpAll) {
13346                        perm.dump(pw, "      ");
13347                    }
13348                }
13349            }
13350        }
13351
13352        if (!printedAnything) {
13353            pw.println("  (nothing)");
13354        }
13355    }
13356
13357    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13358            int opti, boolean dumpAll, String dumpPackage) {
13359        boolean printed = false;
13360
13361        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13362
13363        if (mIntentSenderRecords.size() > 0) {
13364            Iterator<WeakReference<PendingIntentRecord>> it
13365                    = mIntentSenderRecords.values().iterator();
13366            while (it.hasNext()) {
13367                WeakReference<PendingIntentRecord> ref = it.next();
13368                PendingIntentRecord rec = ref != null ? ref.get(): null;
13369                if (dumpPackage != null && (rec == null
13370                        || !dumpPackage.equals(rec.key.packageName))) {
13371                    continue;
13372                }
13373                printed = true;
13374                if (rec != null) {
13375                    pw.print("  * "); pw.println(rec);
13376                    if (dumpAll) {
13377                        rec.dump(pw, "    ");
13378                    }
13379                } else {
13380                    pw.print("  * "); pw.println(ref);
13381                }
13382            }
13383        }
13384
13385        if (!printed) {
13386            pw.println("  (nothing)");
13387        }
13388    }
13389
13390    private static final int dumpProcessList(PrintWriter pw,
13391            ActivityManagerService service, List list,
13392            String prefix, String normalLabel, String persistentLabel,
13393            String dumpPackage) {
13394        int numPers = 0;
13395        final int N = list.size()-1;
13396        for (int i=N; i>=0; i--) {
13397            ProcessRecord r = (ProcessRecord)list.get(i);
13398            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13399                continue;
13400            }
13401            pw.println(String.format("%s%s #%2d: %s",
13402                    prefix, (r.persistent ? persistentLabel : normalLabel),
13403                    i, r.toString()));
13404            if (r.persistent) {
13405                numPers++;
13406            }
13407        }
13408        return numPers;
13409    }
13410
13411    private static final boolean dumpProcessOomList(PrintWriter pw,
13412            ActivityManagerService service, List<ProcessRecord> origList,
13413            String prefix, String normalLabel, String persistentLabel,
13414            boolean inclDetails, String dumpPackage) {
13415
13416        ArrayList<Pair<ProcessRecord, Integer>> list
13417                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13418        for (int i=0; i<origList.size(); i++) {
13419            ProcessRecord r = origList.get(i);
13420            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13421                continue;
13422            }
13423            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13424        }
13425
13426        if (list.size() <= 0) {
13427            return false;
13428        }
13429
13430        Comparator<Pair<ProcessRecord, Integer>> comparator
13431                = new Comparator<Pair<ProcessRecord, Integer>>() {
13432            @Override
13433            public int compare(Pair<ProcessRecord, Integer> object1,
13434                    Pair<ProcessRecord, Integer> object2) {
13435                if (object1.first.setAdj != object2.first.setAdj) {
13436                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13437                }
13438                if (object1.second.intValue() != object2.second.intValue()) {
13439                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13440                }
13441                return 0;
13442            }
13443        };
13444
13445        Collections.sort(list, comparator);
13446
13447        final long curRealtime = SystemClock.elapsedRealtime();
13448        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13449        final long curUptime = SystemClock.uptimeMillis();
13450        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13451
13452        for (int i=list.size()-1; i>=0; i--) {
13453            ProcessRecord r = list.get(i).first;
13454            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13455            char schedGroup;
13456            switch (r.setSchedGroup) {
13457                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13458                    schedGroup = 'B';
13459                    break;
13460                case Process.THREAD_GROUP_DEFAULT:
13461                    schedGroup = 'F';
13462                    break;
13463                default:
13464                    schedGroup = '?';
13465                    break;
13466            }
13467            char foreground;
13468            if (r.foregroundActivities) {
13469                foreground = 'A';
13470            } else if (r.foregroundServices) {
13471                foreground = 'S';
13472            } else {
13473                foreground = ' ';
13474            }
13475            String procState = ProcessList.makeProcStateString(r.curProcState);
13476            pw.print(prefix);
13477            pw.print(r.persistent ? persistentLabel : normalLabel);
13478            pw.print(" #");
13479            int num = (origList.size()-1)-list.get(i).second;
13480            if (num < 10) pw.print(' ');
13481            pw.print(num);
13482            pw.print(": ");
13483            pw.print(oomAdj);
13484            pw.print(' ');
13485            pw.print(schedGroup);
13486            pw.print('/');
13487            pw.print(foreground);
13488            pw.print('/');
13489            pw.print(procState);
13490            pw.print(" trm:");
13491            if (r.trimMemoryLevel < 10) pw.print(' ');
13492            pw.print(r.trimMemoryLevel);
13493            pw.print(' ');
13494            pw.print(r.toShortString());
13495            pw.print(" (");
13496            pw.print(r.adjType);
13497            pw.println(')');
13498            if (r.adjSource != null || r.adjTarget != null) {
13499                pw.print(prefix);
13500                pw.print("    ");
13501                if (r.adjTarget instanceof ComponentName) {
13502                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13503                } else if (r.adjTarget != null) {
13504                    pw.print(r.adjTarget.toString());
13505                } else {
13506                    pw.print("{null}");
13507                }
13508                pw.print("<=");
13509                if (r.adjSource instanceof ProcessRecord) {
13510                    pw.print("Proc{");
13511                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13512                    pw.println("}");
13513                } else if (r.adjSource != null) {
13514                    pw.println(r.adjSource.toString());
13515                } else {
13516                    pw.println("{null}");
13517                }
13518            }
13519            if (inclDetails) {
13520                pw.print(prefix);
13521                pw.print("    ");
13522                pw.print("oom: max="); pw.print(r.maxAdj);
13523                pw.print(" curRaw="); pw.print(r.curRawAdj);
13524                pw.print(" setRaw="); pw.print(r.setRawAdj);
13525                pw.print(" cur="); pw.print(r.curAdj);
13526                pw.print(" set="); pw.println(r.setAdj);
13527                pw.print(prefix);
13528                pw.print("    ");
13529                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13530                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13531                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
13532                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
13533                pw.println();
13534                pw.print(prefix);
13535                pw.print("    ");
13536                pw.print("cached="); pw.print(r.cached);
13537                pw.print(" empty="); pw.print(r.empty);
13538                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13539
13540                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13541                    if (r.lastWakeTime != 0) {
13542                        long wtime;
13543                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13544                        synchronized (stats) {
13545                            wtime = stats.getProcessWakeTime(r.info.uid,
13546                                    r.pid, curRealtime);
13547                        }
13548                        long timeUsed = wtime - r.lastWakeTime;
13549                        pw.print(prefix);
13550                        pw.print("    ");
13551                        pw.print("keep awake over ");
13552                        TimeUtils.formatDuration(realtimeSince, pw);
13553                        pw.print(" used ");
13554                        TimeUtils.formatDuration(timeUsed, pw);
13555                        pw.print(" (");
13556                        pw.print((timeUsed*100)/realtimeSince);
13557                        pw.println("%)");
13558                    }
13559                    if (r.lastCpuTime != 0) {
13560                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13561                        pw.print(prefix);
13562                        pw.print("    ");
13563                        pw.print("run cpu over ");
13564                        TimeUtils.formatDuration(uptimeSince, pw);
13565                        pw.print(" used ");
13566                        TimeUtils.formatDuration(timeUsed, pw);
13567                        pw.print(" (");
13568                        pw.print((timeUsed*100)/uptimeSince);
13569                        pw.println("%)");
13570                    }
13571                }
13572            }
13573        }
13574        return true;
13575    }
13576
13577    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13578            String[] args) {
13579        ArrayList<ProcessRecord> procs;
13580        synchronized (this) {
13581            if (args != null && args.length > start
13582                    && args[start].charAt(0) != '-') {
13583                procs = new ArrayList<ProcessRecord>();
13584                int pid = -1;
13585                try {
13586                    pid = Integer.parseInt(args[start]);
13587                } catch (NumberFormatException e) {
13588                }
13589                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13590                    ProcessRecord proc = mLruProcesses.get(i);
13591                    if (proc.pid == pid) {
13592                        procs.add(proc);
13593                    } else if (allPkgs && proc.pkgList != null
13594                            && proc.pkgList.containsKey(args[start])) {
13595                        procs.add(proc);
13596                    } else if (proc.processName.equals(args[start])) {
13597                        procs.add(proc);
13598                    }
13599                }
13600                if (procs.size() <= 0) {
13601                    return null;
13602                }
13603            } else {
13604                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13605            }
13606        }
13607        return procs;
13608    }
13609
13610    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13611            PrintWriter pw, String[] args) {
13612        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13613        if (procs == null) {
13614            pw.println("No process found for: " + args[0]);
13615            return;
13616        }
13617
13618        long uptime = SystemClock.uptimeMillis();
13619        long realtime = SystemClock.elapsedRealtime();
13620        pw.println("Applications Graphics Acceleration Info:");
13621        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13622
13623        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13624            ProcessRecord r = procs.get(i);
13625            if (r.thread != null) {
13626                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13627                pw.flush();
13628                try {
13629                    TransferPipe tp = new TransferPipe();
13630                    try {
13631                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13632                        tp.go(fd);
13633                    } finally {
13634                        tp.kill();
13635                    }
13636                } catch (IOException e) {
13637                    pw.println("Failure while dumping the app: " + r);
13638                    pw.flush();
13639                } catch (RemoteException e) {
13640                    pw.println("Got a RemoteException while dumping the app " + r);
13641                    pw.flush();
13642                }
13643            }
13644        }
13645    }
13646
13647    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13648        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13649        if (procs == null) {
13650            pw.println("No process found for: " + args[0]);
13651            return;
13652        }
13653
13654        pw.println("Applications Database Info:");
13655
13656        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13657            ProcessRecord r = procs.get(i);
13658            if (r.thread != null) {
13659                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13660                pw.flush();
13661                try {
13662                    TransferPipe tp = new TransferPipe();
13663                    try {
13664                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13665                        tp.go(fd);
13666                    } finally {
13667                        tp.kill();
13668                    }
13669                } catch (IOException e) {
13670                    pw.println("Failure while dumping the app: " + r);
13671                    pw.flush();
13672                } catch (RemoteException e) {
13673                    pw.println("Got a RemoteException while dumping the app " + r);
13674                    pw.flush();
13675                }
13676            }
13677        }
13678    }
13679
13680    final static class MemItem {
13681        final boolean isProc;
13682        final String label;
13683        final String shortLabel;
13684        final long pss;
13685        final int id;
13686        final boolean hasActivities;
13687        ArrayList<MemItem> subitems;
13688
13689        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13690                boolean _hasActivities) {
13691            isProc = true;
13692            label = _label;
13693            shortLabel = _shortLabel;
13694            pss = _pss;
13695            id = _id;
13696            hasActivities = _hasActivities;
13697        }
13698
13699        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13700            isProc = false;
13701            label = _label;
13702            shortLabel = _shortLabel;
13703            pss = _pss;
13704            id = _id;
13705            hasActivities = false;
13706        }
13707    }
13708
13709    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13710            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13711        if (sort && !isCompact) {
13712            Collections.sort(items, new Comparator<MemItem>() {
13713                @Override
13714                public int compare(MemItem lhs, MemItem rhs) {
13715                    if (lhs.pss < rhs.pss) {
13716                        return 1;
13717                    } else if (lhs.pss > rhs.pss) {
13718                        return -1;
13719                    }
13720                    return 0;
13721                }
13722            });
13723        }
13724
13725        for (int i=0; i<items.size(); i++) {
13726            MemItem mi = items.get(i);
13727            if (!isCompact) {
13728                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13729            } else if (mi.isProc) {
13730                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13731                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13732                pw.println(mi.hasActivities ? ",a" : ",e");
13733            } else {
13734                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13735                pw.println(mi.pss);
13736            }
13737            if (mi.subitems != null) {
13738                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13739                        true, isCompact);
13740            }
13741        }
13742    }
13743
13744    // These are in KB.
13745    static final long[] DUMP_MEM_BUCKETS = new long[] {
13746        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13747        120*1024, 160*1024, 200*1024,
13748        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13749        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13750    };
13751
13752    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13753            boolean stackLike) {
13754        int start = label.lastIndexOf('.');
13755        if (start >= 0) start++;
13756        else start = 0;
13757        int end = label.length();
13758        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13759            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13760                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13761                out.append(bucket);
13762                out.append(stackLike ? "MB." : "MB ");
13763                out.append(label, start, end);
13764                return;
13765            }
13766        }
13767        out.append(memKB/1024);
13768        out.append(stackLike ? "MB." : "MB ");
13769        out.append(label, start, end);
13770    }
13771
13772    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13773            ProcessList.NATIVE_ADJ,
13774            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13775            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13776            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13777            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13778            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13779            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13780    };
13781    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13782            "Native",
13783            "System", "Persistent", "Persistent Service", "Foreground",
13784            "Visible", "Perceptible",
13785            "Heavy Weight", "Backup",
13786            "A Services", "Home",
13787            "Previous", "B Services", "Cached"
13788    };
13789    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13790            "native",
13791            "sys", "pers", "persvc", "fore",
13792            "vis", "percept",
13793            "heavy", "backup",
13794            "servicea", "home",
13795            "prev", "serviceb", "cached"
13796    };
13797
13798    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13799            long realtime, boolean isCheckinRequest, boolean isCompact) {
13800        if (isCheckinRequest || isCompact) {
13801            // short checkin version
13802            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13803        } else {
13804            pw.println("Applications Memory Usage (kB):");
13805            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13806        }
13807    }
13808
13809    private static final int KSM_SHARED = 0;
13810    private static final int KSM_SHARING = 1;
13811    private static final int KSM_UNSHARED = 2;
13812    private static final int KSM_VOLATILE = 3;
13813
13814    private final long[] getKsmInfo() {
13815        long[] longOut = new long[4];
13816        final int[] SINGLE_LONG_FORMAT = new int[] {
13817            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13818        };
13819        long[] longTmp = new long[1];
13820        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13821                SINGLE_LONG_FORMAT, null, longTmp, null);
13822        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13823        longTmp[0] = 0;
13824        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13825                SINGLE_LONG_FORMAT, null, longTmp, null);
13826        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13827        longTmp[0] = 0;
13828        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13829                SINGLE_LONG_FORMAT, null, longTmp, null);
13830        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13831        longTmp[0] = 0;
13832        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13833                SINGLE_LONG_FORMAT, null, longTmp, null);
13834        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13835        return longOut;
13836    }
13837
13838    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13839            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13840        boolean dumpDetails = false;
13841        boolean dumpFullDetails = false;
13842        boolean dumpDalvik = false;
13843        boolean oomOnly = false;
13844        boolean isCompact = false;
13845        boolean localOnly = false;
13846        boolean packages = false;
13847
13848        int opti = 0;
13849        while (opti < args.length) {
13850            String opt = args[opti];
13851            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13852                break;
13853            }
13854            opti++;
13855            if ("-a".equals(opt)) {
13856                dumpDetails = true;
13857                dumpFullDetails = true;
13858                dumpDalvik = true;
13859            } else if ("-d".equals(opt)) {
13860                dumpDalvik = true;
13861            } else if ("-c".equals(opt)) {
13862                isCompact = true;
13863            } else if ("--oom".equals(opt)) {
13864                oomOnly = true;
13865            } else if ("--local".equals(opt)) {
13866                localOnly = true;
13867            } else if ("--package".equals(opt)) {
13868                packages = true;
13869            } else if ("-h".equals(opt)) {
13870                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13871                pw.println("  -a: include all available information for each process.");
13872                pw.println("  -d: include dalvik details when dumping process details.");
13873                pw.println("  -c: dump in a compact machine-parseable representation.");
13874                pw.println("  --oom: only show processes organized by oom adj.");
13875                pw.println("  --local: only collect details locally, don't call process.");
13876                pw.println("  --package: interpret process arg as package, dumping all");
13877                pw.println("             processes that have loaded that package.");
13878                pw.println("If [process] is specified it can be the name or ");
13879                pw.println("pid of a specific process to dump.");
13880                return;
13881            } else {
13882                pw.println("Unknown argument: " + opt + "; use -h for help");
13883            }
13884        }
13885
13886        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13887        long uptime = SystemClock.uptimeMillis();
13888        long realtime = SystemClock.elapsedRealtime();
13889        final long[] tmpLong = new long[1];
13890
13891        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13892        if (procs == null) {
13893            // No Java processes.  Maybe they want to print a native process.
13894            if (args != null && args.length > opti
13895                    && args[opti].charAt(0) != '-') {
13896                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13897                        = new ArrayList<ProcessCpuTracker.Stats>();
13898                updateCpuStatsNow();
13899                int findPid = -1;
13900                try {
13901                    findPid = Integer.parseInt(args[opti]);
13902                } catch (NumberFormatException e) {
13903                }
13904                synchronized (mProcessCpuTracker) {
13905                    final int N = mProcessCpuTracker.countStats();
13906                    for (int i=0; i<N; i++) {
13907                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13908                        if (st.pid == findPid || (st.baseName != null
13909                                && st.baseName.equals(args[opti]))) {
13910                            nativeProcs.add(st);
13911                        }
13912                    }
13913                }
13914                if (nativeProcs.size() > 0) {
13915                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13916                            isCompact);
13917                    Debug.MemoryInfo mi = null;
13918                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13919                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13920                        final int pid = r.pid;
13921                        if (!isCheckinRequest && dumpDetails) {
13922                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13923                        }
13924                        if (mi == null) {
13925                            mi = new Debug.MemoryInfo();
13926                        }
13927                        if (dumpDetails || (!brief && !oomOnly)) {
13928                            Debug.getMemoryInfo(pid, mi);
13929                        } else {
13930                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13931                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13932                        }
13933                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13934                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13935                        if (isCheckinRequest) {
13936                            pw.println();
13937                        }
13938                    }
13939                    return;
13940                }
13941            }
13942            pw.println("No process found for: " + args[opti]);
13943            return;
13944        }
13945
13946        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13947            dumpDetails = true;
13948        }
13949
13950        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13951
13952        String[] innerArgs = new String[args.length-opti];
13953        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13954
13955        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13956        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13957        long nativePss = 0;
13958        long dalvikPss = 0;
13959        long otherPss = 0;
13960        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13961
13962        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13963        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13964                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13965
13966        long totalPss = 0;
13967        long cachedPss = 0;
13968
13969        Debug.MemoryInfo mi = null;
13970        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13971            final ProcessRecord r = procs.get(i);
13972            final IApplicationThread thread;
13973            final int pid;
13974            final int oomAdj;
13975            final boolean hasActivities;
13976            synchronized (this) {
13977                thread = r.thread;
13978                pid = r.pid;
13979                oomAdj = r.getSetAdjWithServices();
13980                hasActivities = r.activities.size() > 0;
13981            }
13982            if (thread != null) {
13983                if (!isCheckinRequest && dumpDetails) {
13984                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13985                }
13986                if (mi == null) {
13987                    mi = new Debug.MemoryInfo();
13988                }
13989                if (dumpDetails || (!brief && !oomOnly)) {
13990                    Debug.getMemoryInfo(pid, mi);
13991                } else {
13992                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13993                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13994                }
13995                if (dumpDetails) {
13996                    if (localOnly) {
13997                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13998                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13999                        if (isCheckinRequest) {
14000                            pw.println();
14001                        }
14002                    } else {
14003                        try {
14004                            pw.flush();
14005                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14006                                    dumpDalvik, innerArgs);
14007                        } catch (RemoteException e) {
14008                            if (!isCheckinRequest) {
14009                                pw.println("Got RemoteException!");
14010                                pw.flush();
14011                            }
14012                        }
14013                    }
14014                }
14015
14016                final long myTotalPss = mi.getTotalPss();
14017                final long myTotalUss = mi.getTotalUss();
14018
14019                synchronized (this) {
14020                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14021                        // Record this for posterity if the process has been stable.
14022                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14023                    }
14024                }
14025
14026                if (!isCheckinRequest && mi != null) {
14027                    totalPss += myTotalPss;
14028                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14029                            (hasActivities ? " / activities)" : ")"),
14030                            r.processName, myTotalPss, pid, hasActivities);
14031                    procMems.add(pssItem);
14032                    procMemsMap.put(pid, pssItem);
14033
14034                    nativePss += mi.nativePss;
14035                    dalvikPss += mi.dalvikPss;
14036                    otherPss += mi.otherPss;
14037                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14038                        long mem = mi.getOtherPss(j);
14039                        miscPss[j] += mem;
14040                        otherPss -= mem;
14041                    }
14042
14043                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14044                        cachedPss += myTotalPss;
14045                    }
14046
14047                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14048                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14049                                || oomIndex == (oomPss.length-1)) {
14050                            oomPss[oomIndex] += myTotalPss;
14051                            if (oomProcs[oomIndex] == null) {
14052                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14053                            }
14054                            oomProcs[oomIndex].add(pssItem);
14055                            break;
14056                        }
14057                    }
14058                }
14059            }
14060        }
14061
14062        long nativeProcTotalPss = 0;
14063
14064        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14065            // If we are showing aggregations, also look for native processes to
14066            // include so that our aggregations are more accurate.
14067            updateCpuStatsNow();
14068            mi = null;
14069            synchronized (mProcessCpuTracker) {
14070                final int N = mProcessCpuTracker.countStats();
14071                for (int i=0; i<N; i++) {
14072                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14073                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14074                        if (mi == null) {
14075                            mi = new Debug.MemoryInfo();
14076                        }
14077                        if (!brief && !oomOnly) {
14078                            Debug.getMemoryInfo(st.pid, mi);
14079                        } else {
14080                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14081                            mi.nativePrivateDirty = (int)tmpLong[0];
14082                        }
14083
14084                        final long myTotalPss = mi.getTotalPss();
14085                        totalPss += myTotalPss;
14086                        nativeProcTotalPss += myTotalPss;
14087
14088                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14089                                st.name, myTotalPss, st.pid, false);
14090                        procMems.add(pssItem);
14091
14092                        nativePss += mi.nativePss;
14093                        dalvikPss += mi.dalvikPss;
14094                        otherPss += mi.otherPss;
14095                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14096                            long mem = mi.getOtherPss(j);
14097                            miscPss[j] += mem;
14098                            otherPss -= mem;
14099                        }
14100                        oomPss[0] += myTotalPss;
14101                        if (oomProcs[0] == null) {
14102                            oomProcs[0] = new ArrayList<MemItem>();
14103                        }
14104                        oomProcs[0].add(pssItem);
14105                    }
14106                }
14107            }
14108
14109            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14110
14111            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14112            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14113            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14114            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14115                String label = Debug.MemoryInfo.getOtherLabel(j);
14116                catMems.add(new MemItem(label, label, miscPss[j], j));
14117            }
14118
14119            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14120            for (int j=0; j<oomPss.length; j++) {
14121                if (oomPss[j] != 0) {
14122                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14123                            : DUMP_MEM_OOM_LABEL[j];
14124                    MemItem item = new MemItem(label, label, oomPss[j],
14125                            DUMP_MEM_OOM_ADJ[j]);
14126                    item.subitems = oomProcs[j];
14127                    oomMems.add(item);
14128                }
14129            }
14130
14131            if (!brief && !oomOnly && !isCompact) {
14132                pw.println();
14133                pw.println("Total PSS by process:");
14134                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14135                pw.println();
14136            }
14137            if (!isCompact) {
14138                pw.println("Total PSS by OOM adjustment:");
14139            }
14140            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14141            if (!brief && !oomOnly) {
14142                PrintWriter out = categoryPw != null ? categoryPw : pw;
14143                if (!isCompact) {
14144                    out.println();
14145                    out.println("Total PSS by category:");
14146                }
14147                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14148            }
14149            if (!isCompact) {
14150                pw.println();
14151            }
14152            MemInfoReader memInfo = new MemInfoReader();
14153            memInfo.readMemInfo();
14154            if (nativeProcTotalPss > 0) {
14155                synchronized (this) {
14156                    final long cachedKb = memInfo.getCachedSizeKb();
14157                    final long freeKb = memInfo.getFreeSizeKb();
14158                    final long zramKb = memInfo.getZramTotalSizeKb();
14159                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14160                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14161                            kernelKb*1024, nativeProcTotalPss*1024);
14162                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14163                            nativeProcTotalPss);
14164                }
14165            }
14166            if (!brief) {
14167                if (!isCompact) {
14168                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14169                    pw.print(" kB (status ");
14170                    switch (mLastMemoryLevel) {
14171                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14172                            pw.println("normal)");
14173                            break;
14174                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14175                            pw.println("moderate)");
14176                            break;
14177                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14178                            pw.println("low)");
14179                            break;
14180                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14181                            pw.println("critical)");
14182                            break;
14183                        default:
14184                            pw.print(mLastMemoryLevel);
14185                            pw.println(")");
14186                            break;
14187                    }
14188                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14189                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14190                            pw.print(cachedPss); pw.print(" cached pss + ");
14191                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14192                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14193                } else {
14194                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14195                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14196                            + memInfo.getFreeSizeKb()); pw.print(",");
14197                    pw.println(totalPss - cachedPss);
14198                }
14199            }
14200            if (!isCompact) {
14201                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14202                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14203                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14204                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14205                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14206                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14207                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14208            }
14209            if (!brief) {
14210                if (memInfo.getZramTotalSizeKb() != 0) {
14211                    if (!isCompact) {
14212                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14213                                pw.print(" kB physical used for ");
14214                                pw.print(memInfo.getSwapTotalSizeKb()
14215                                        - memInfo.getSwapFreeSizeKb());
14216                                pw.print(" kB in swap (");
14217                                pw.print(memInfo.getSwapTotalSizeKb());
14218                                pw.println(" kB total swap)");
14219                    } else {
14220                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14221                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14222                                pw.println(memInfo.getSwapFreeSizeKb());
14223                    }
14224                }
14225                final long[] ksm = getKsmInfo();
14226                if (!isCompact) {
14227                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14228                            || ksm[KSM_VOLATILE] != 0) {
14229                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14230                                pw.print(" kB saved from shared ");
14231                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14232                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14233                                pw.print(" kB unshared; ");
14234                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14235                    }
14236                    pw.print("   Tuning: ");
14237                    pw.print(ActivityManager.staticGetMemoryClass());
14238                    pw.print(" (large ");
14239                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14240                    pw.print("), oom ");
14241                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14242                    pw.print(" kB");
14243                    pw.print(", restore limit ");
14244                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14245                    pw.print(" kB");
14246                    if (ActivityManager.isLowRamDeviceStatic()) {
14247                        pw.print(" (low-ram)");
14248                    }
14249                    if (ActivityManager.isHighEndGfx()) {
14250                        pw.print(" (high-end-gfx)");
14251                    }
14252                    pw.println();
14253                } else {
14254                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14255                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14256                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14257                    pw.print("tuning,");
14258                    pw.print(ActivityManager.staticGetMemoryClass());
14259                    pw.print(',');
14260                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14261                    pw.print(',');
14262                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14263                    if (ActivityManager.isLowRamDeviceStatic()) {
14264                        pw.print(",low-ram");
14265                    }
14266                    if (ActivityManager.isHighEndGfx()) {
14267                        pw.print(",high-end-gfx");
14268                    }
14269                    pw.println();
14270                }
14271            }
14272        }
14273    }
14274
14275    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14276            long memtrack, String name) {
14277        sb.append("  ");
14278        sb.append(ProcessList.makeOomAdjString(oomAdj));
14279        sb.append(' ');
14280        sb.append(ProcessList.makeProcStateString(procState));
14281        sb.append(' ');
14282        ProcessList.appendRamKb(sb, pss);
14283        sb.append(" kB: ");
14284        sb.append(name);
14285        if (memtrack > 0) {
14286            sb.append(" (");
14287            sb.append(memtrack);
14288            sb.append(" kB memtrack)");
14289        }
14290    }
14291
14292    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14293        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14294        sb.append(" (pid ");
14295        sb.append(mi.pid);
14296        sb.append(") ");
14297        sb.append(mi.adjType);
14298        sb.append('\n');
14299        if (mi.adjReason != null) {
14300            sb.append("                      ");
14301            sb.append(mi.adjReason);
14302            sb.append('\n');
14303        }
14304    }
14305
14306    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14307        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14308        for (int i=0, N=memInfos.size(); i<N; i++) {
14309            ProcessMemInfo mi = memInfos.get(i);
14310            infoMap.put(mi.pid, mi);
14311        }
14312        updateCpuStatsNow();
14313        long[] memtrackTmp = new long[1];
14314        synchronized (mProcessCpuTracker) {
14315            final int N = mProcessCpuTracker.countStats();
14316            for (int i=0; i<N; i++) {
14317                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14318                if (st.vsize > 0) {
14319                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14320                    if (pss > 0) {
14321                        if (infoMap.indexOfKey(st.pid) < 0) {
14322                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14323                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14324                            mi.pss = pss;
14325                            mi.memtrack = memtrackTmp[0];
14326                            memInfos.add(mi);
14327                        }
14328                    }
14329                }
14330            }
14331        }
14332
14333        long totalPss = 0;
14334        long totalMemtrack = 0;
14335        for (int i=0, N=memInfos.size(); i<N; i++) {
14336            ProcessMemInfo mi = memInfos.get(i);
14337            if (mi.pss == 0) {
14338                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14339                mi.memtrack = memtrackTmp[0];
14340            }
14341            totalPss += mi.pss;
14342            totalMemtrack += mi.memtrack;
14343        }
14344        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14345            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14346                if (lhs.oomAdj != rhs.oomAdj) {
14347                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14348                }
14349                if (lhs.pss != rhs.pss) {
14350                    return lhs.pss < rhs.pss ? 1 : -1;
14351                }
14352                return 0;
14353            }
14354        });
14355
14356        StringBuilder tag = new StringBuilder(128);
14357        StringBuilder stack = new StringBuilder(128);
14358        tag.append("Low on memory -- ");
14359        appendMemBucket(tag, totalPss, "total", false);
14360        appendMemBucket(stack, totalPss, "total", true);
14361
14362        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14363        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14364        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14365
14366        boolean firstLine = true;
14367        int lastOomAdj = Integer.MIN_VALUE;
14368        long extraNativeRam = 0;
14369        long extraNativeMemtrack = 0;
14370        long cachedPss = 0;
14371        for (int i=0, N=memInfos.size(); i<N; i++) {
14372            ProcessMemInfo mi = memInfos.get(i);
14373
14374            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14375                cachedPss += mi.pss;
14376            }
14377
14378            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14379                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14380                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14381                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14382                if (lastOomAdj != mi.oomAdj) {
14383                    lastOomAdj = mi.oomAdj;
14384                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14385                        tag.append(" / ");
14386                    }
14387                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14388                        if (firstLine) {
14389                            stack.append(":");
14390                            firstLine = false;
14391                        }
14392                        stack.append("\n\t at ");
14393                    } else {
14394                        stack.append("$");
14395                    }
14396                } else {
14397                    tag.append(" ");
14398                    stack.append("$");
14399                }
14400                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14401                    appendMemBucket(tag, mi.pss, mi.name, false);
14402                }
14403                appendMemBucket(stack, mi.pss, mi.name, true);
14404                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14405                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14406                    stack.append("(");
14407                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14408                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14409                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14410                            stack.append(":");
14411                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14412                        }
14413                    }
14414                    stack.append(")");
14415                }
14416            }
14417
14418            appendMemInfo(fullNativeBuilder, mi);
14419            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14420                // The short form only has native processes that are >= 512K.
14421                if (mi.pss >= 512) {
14422                    appendMemInfo(shortNativeBuilder, mi);
14423                } else {
14424                    extraNativeRam += mi.pss;
14425                    extraNativeMemtrack += mi.memtrack;
14426                }
14427            } else {
14428                // Short form has all other details, but if we have collected RAM
14429                // from smaller native processes let's dump a summary of that.
14430                if (extraNativeRam > 0) {
14431                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14432                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14433                    shortNativeBuilder.append('\n');
14434                    extraNativeRam = 0;
14435                }
14436                appendMemInfo(fullJavaBuilder, mi);
14437            }
14438        }
14439
14440        fullJavaBuilder.append("           ");
14441        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14442        fullJavaBuilder.append(" kB: TOTAL");
14443        if (totalMemtrack > 0) {
14444            fullJavaBuilder.append(" (");
14445            fullJavaBuilder.append(totalMemtrack);
14446            fullJavaBuilder.append(" kB memtrack)");
14447        } else {
14448        }
14449        fullJavaBuilder.append("\n");
14450
14451        MemInfoReader memInfo = new MemInfoReader();
14452        memInfo.readMemInfo();
14453        final long[] infos = memInfo.getRawInfo();
14454
14455        StringBuilder memInfoBuilder = new StringBuilder(1024);
14456        Debug.getMemInfo(infos);
14457        memInfoBuilder.append("  MemInfo: ");
14458        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14459        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14460        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14461        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14462        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14463        memInfoBuilder.append("           ");
14464        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14465        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14466        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14467        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14468        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14469            memInfoBuilder.append("  ZRAM: ");
14470            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14471            memInfoBuilder.append(" kB RAM, ");
14472            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14473            memInfoBuilder.append(" kB swap total, ");
14474            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14475            memInfoBuilder.append(" kB swap free\n");
14476        }
14477        final long[] ksm = getKsmInfo();
14478        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14479                || ksm[KSM_VOLATILE] != 0) {
14480            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14481            memInfoBuilder.append(" kB saved from shared ");
14482            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14483            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14484            memInfoBuilder.append(" kB unshared; ");
14485            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14486        }
14487        memInfoBuilder.append("  Free RAM: ");
14488        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14489                + memInfo.getFreeSizeKb());
14490        memInfoBuilder.append(" kB\n");
14491        memInfoBuilder.append("  Used RAM: ");
14492        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14493        memInfoBuilder.append(" kB\n");
14494        memInfoBuilder.append("  Lost RAM: ");
14495        memInfoBuilder.append(memInfo.getTotalSizeKb()
14496                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14497                - memInfo.getKernelUsedSizeKb());
14498        memInfoBuilder.append(" kB\n");
14499        Slog.i(TAG, "Low on memory:");
14500        Slog.i(TAG, shortNativeBuilder.toString());
14501        Slog.i(TAG, fullJavaBuilder.toString());
14502        Slog.i(TAG, memInfoBuilder.toString());
14503
14504        StringBuilder dropBuilder = new StringBuilder(1024);
14505        /*
14506        StringWriter oomSw = new StringWriter();
14507        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14508        StringWriter catSw = new StringWriter();
14509        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14510        String[] emptyArgs = new String[] { };
14511        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14512        oomPw.flush();
14513        String oomString = oomSw.toString();
14514        */
14515        dropBuilder.append("Low on memory:");
14516        dropBuilder.append(stack);
14517        dropBuilder.append('\n');
14518        dropBuilder.append(fullNativeBuilder);
14519        dropBuilder.append(fullJavaBuilder);
14520        dropBuilder.append('\n');
14521        dropBuilder.append(memInfoBuilder);
14522        dropBuilder.append('\n');
14523        /*
14524        dropBuilder.append(oomString);
14525        dropBuilder.append('\n');
14526        */
14527        StringWriter catSw = new StringWriter();
14528        synchronized (ActivityManagerService.this) {
14529            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14530            String[] emptyArgs = new String[] { };
14531            catPw.println();
14532            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14533            catPw.println();
14534            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14535                    false, false, null);
14536            catPw.println();
14537            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14538            catPw.flush();
14539        }
14540        dropBuilder.append(catSw.toString());
14541        addErrorToDropBox("lowmem", null, "system_server", null,
14542                null, tag.toString(), dropBuilder.toString(), null, null);
14543        //Slog.i(TAG, "Sent to dropbox:");
14544        //Slog.i(TAG, dropBuilder.toString());
14545        synchronized (ActivityManagerService.this) {
14546            long now = SystemClock.uptimeMillis();
14547            if (mLastMemUsageReportTime < now) {
14548                mLastMemUsageReportTime = now;
14549            }
14550        }
14551    }
14552
14553    /**
14554     * Searches array of arguments for the specified string
14555     * @param args array of argument strings
14556     * @param value value to search for
14557     * @return true if the value is contained in the array
14558     */
14559    private static boolean scanArgs(String[] args, String value) {
14560        if (args != null) {
14561            for (String arg : args) {
14562                if (value.equals(arg)) {
14563                    return true;
14564                }
14565            }
14566        }
14567        return false;
14568    }
14569
14570    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14571            ContentProviderRecord cpr, boolean always) {
14572        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14573
14574        if (!inLaunching || always) {
14575            synchronized (cpr) {
14576                cpr.launchingApp = null;
14577                cpr.notifyAll();
14578            }
14579            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14580            String names[] = cpr.info.authority.split(";");
14581            for (int j = 0; j < names.length; j++) {
14582                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14583            }
14584        }
14585
14586        for (int i=0; i<cpr.connections.size(); i++) {
14587            ContentProviderConnection conn = cpr.connections.get(i);
14588            if (conn.waiting) {
14589                // If this connection is waiting for the provider, then we don't
14590                // need to mess with its process unless we are always removing
14591                // or for some reason the provider is not currently launching.
14592                if (inLaunching && !always) {
14593                    continue;
14594                }
14595            }
14596            ProcessRecord capp = conn.client;
14597            conn.dead = true;
14598            if (conn.stableCount > 0) {
14599                if (!capp.persistent && capp.thread != null
14600                        && capp.pid != 0
14601                        && capp.pid != MY_PID) {
14602                    capp.kill("depends on provider "
14603                            + cpr.name.flattenToShortString()
14604                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14605                }
14606            } else if (capp.thread != null && conn.provider.provider != null) {
14607                try {
14608                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14609                } catch (RemoteException e) {
14610                }
14611                // In the protocol here, we don't expect the client to correctly
14612                // clean up this connection, we'll just remove it.
14613                cpr.connections.remove(i);
14614                if (conn.client.conProviders.remove(conn)) {
14615                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14616                }
14617            }
14618        }
14619
14620        if (inLaunching && always) {
14621            mLaunchingProviders.remove(cpr);
14622        }
14623        return inLaunching;
14624    }
14625
14626    /**
14627     * Main code for cleaning up a process when it has gone away.  This is
14628     * called both as a result of the process dying, or directly when stopping
14629     * a process when running in single process mode.
14630     *
14631     * @return Returns true if the given process has been restarted, so the
14632     * app that was passed in must remain on the process lists.
14633     */
14634    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14635            boolean restarting, boolean allowRestart, int index) {
14636        if (index >= 0) {
14637            removeLruProcessLocked(app);
14638            ProcessList.remove(app.pid);
14639        }
14640
14641        mProcessesToGc.remove(app);
14642        mPendingPssProcesses.remove(app);
14643
14644        // Dismiss any open dialogs.
14645        if (app.crashDialog != null && !app.forceCrashReport) {
14646            app.crashDialog.dismiss();
14647            app.crashDialog = null;
14648        }
14649        if (app.anrDialog != null) {
14650            app.anrDialog.dismiss();
14651            app.anrDialog = null;
14652        }
14653        if (app.waitDialog != null) {
14654            app.waitDialog.dismiss();
14655            app.waitDialog = null;
14656        }
14657
14658        app.crashing = false;
14659        app.notResponding = false;
14660
14661        app.resetPackageList(mProcessStats);
14662        app.unlinkDeathRecipient();
14663        app.makeInactive(mProcessStats);
14664        app.waitingToKill = null;
14665        app.forcingToForeground = null;
14666        updateProcessForegroundLocked(app, false, false);
14667        app.foregroundActivities = false;
14668        app.hasShownUi = false;
14669        app.treatLikeActivity = false;
14670        app.hasAboveClient = false;
14671        app.hasClientActivities = false;
14672
14673        mServices.killServicesLocked(app, allowRestart);
14674
14675        boolean restart = false;
14676
14677        // Remove published content providers.
14678        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14679            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14680            final boolean always = app.bad || !allowRestart;
14681            if (removeDyingProviderLocked(app, cpr, always) || always) {
14682                // We left the provider in the launching list, need to
14683                // restart it.
14684                restart = true;
14685            }
14686
14687            cpr.provider = null;
14688            cpr.proc = null;
14689        }
14690        app.pubProviders.clear();
14691
14692        // Take care of any launching providers waiting for this process.
14693        if (checkAppInLaunchingProvidersLocked(app, false)) {
14694            restart = true;
14695        }
14696
14697        // Unregister from connected content providers.
14698        if (!app.conProviders.isEmpty()) {
14699            for (int i=0; i<app.conProviders.size(); i++) {
14700                ContentProviderConnection conn = app.conProviders.get(i);
14701                conn.provider.connections.remove(conn);
14702                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14703                        conn.provider.name);
14704            }
14705            app.conProviders.clear();
14706        }
14707
14708        // At this point there may be remaining entries in mLaunchingProviders
14709        // where we were the only one waiting, so they are no longer of use.
14710        // Look for these and clean up if found.
14711        // XXX Commented out for now.  Trying to figure out a way to reproduce
14712        // the actual situation to identify what is actually going on.
14713        if (false) {
14714            for (int i=0; i<mLaunchingProviders.size(); i++) {
14715                ContentProviderRecord cpr = (ContentProviderRecord)
14716                        mLaunchingProviders.get(i);
14717                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14718                    synchronized (cpr) {
14719                        cpr.launchingApp = null;
14720                        cpr.notifyAll();
14721                    }
14722                }
14723            }
14724        }
14725
14726        skipCurrentReceiverLocked(app);
14727
14728        // Unregister any receivers.
14729        for (int i=app.receivers.size()-1; i>=0; i--) {
14730            removeReceiverLocked(app.receivers.valueAt(i));
14731        }
14732        app.receivers.clear();
14733
14734        // If the app is undergoing backup, tell the backup manager about it
14735        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14736            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
14737                    + mBackupTarget.appInfo + " died during backup");
14738            try {
14739                IBackupManager bm = IBackupManager.Stub.asInterface(
14740                        ServiceManager.getService(Context.BACKUP_SERVICE));
14741                bm.agentDisconnected(app.info.packageName);
14742            } catch (RemoteException e) {
14743                // can't happen; backup manager is local
14744            }
14745        }
14746
14747        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14748            ProcessChangeItem item = mPendingProcessChanges.get(i);
14749            if (item.pid == app.pid) {
14750                mPendingProcessChanges.remove(i);
14751                mAvailProcessChanges.add(item);
14752            }
14753        }
14754        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14755
14756        // If the caller is restarting this app, then leave it in its
14757        // current lists and let the caller take care of it.
14758        if (restarting) {
14759            return false;
14760        }
14761
14762        if (!app.persistent || app.isolated) {
14763            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
14764                    "Removing non-persistent process during cleanup: " + app);
14765            mProcessNames.remove(app.processName, app.uid);
14766            mIsolatedProcesses.remove(app.uid);
14767            if (mHeavyWeightProcess == app) {
14768                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14769                        mHeavyWeightProcess.userId, 0));
14770                mHeavyWeightProcess = null;
14771            }
14772        } else if (!app.removed) {
14773            // This app is persistent, so we need to keep its record around.
14774            // If it is not already on the pending app list, add it there
14775            // and start a new process for it.
14776            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14777                mPersistentStartingProcesses.add(app);
14778                restart = true;
14779            }
14780        }
14781        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
14782                TAG_CLEANUP, "Clean-up removing on hold: " + app);
14783        mProcessesOnHold.remove(app);
14784
14785        if (app == mHomeProcess) {
14786            mHomeProcess = null;
14787        }
14788        if (app == mPreviousProcess) {
14789            mPreviousProcess = null;
14790        }
14791
14792        if (restart && !app.isolated) {
14793            // We have components that still need to be running in the
14794            // process, so re-launch it.
14795            if (index < 0) {
14796                ProcessList.remove(app.pid);
14797            }
14798            mProcessNames.put(app.processName, app.uid, app);
14799            startProcessLocked(app, "restart", app.processName);
14800            return true;
14801        } else if (app.pid > 0 && app.pid != MY_PID) {
14802            // Goodbye!
14803            boolean removed;
14804            synchronized (mPidsSelfLocked) {
14805                mPidsSelfLocked.remove(app.pid);
14806                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14807            }
14808            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14809            if (app.isolated) {
14810                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14811            }
14812            app.setPid(0);
14813        }
14814        return false;
14815    }
14816
14817    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14818        // Look through the content providers we are waiting to have launched,
14819        // and if any run in this process then either schedule a restart of
14820        // the process or kill the client waiting for it if this process has
14821        // gone bad.
14822        int NL = mLaunchingProviders.size();
14823        boolean restart = false;
14824        for (int i=0; i<NL; i++) {
14825            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14826            if (cpr.launchingApp == app) {
14827                if (!alwaysBad && !app.bad) {
14828                    restart = true;
14829                } else {
14830                    removeDyingProviderLocked(app, cpr, true);
14831                    // cpr should have been removed from mLaunchingProviders
14832                    NL = mLaunchingProviders.size();
14833                    i--;
14834                }
14835            }
14836        }
14837        return restart;
14838    }
14839
14840    // =========================================================
14841    // SERVICES
14842    // =========================================================
14843
14844    @Override
14845    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14846            int flags) {
14847        enforceNotIsolatedCaller("getServices");
14848        synchronized (this) {
14849            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14850        }
14851    }
14852
14853    @Override
14854    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14855        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14856        synchronized (this) {
14857            return mServices.getRunningServiceControlPanelLocked(name);
14858        }
14859    }
14860
14861    @Override
14862    public ComponentName startService(IApplicationThread caller, Intent service,
14863            String resolvedType, int userId) {
14864        enforceNotIsolatedCaller("startService");
14865        // Refuse possible leaked file descriptors
14866        if (service != null && service.hasFileDescriptors() == true) {
14867            throw new IllegalArgumentException("File descriptors passed in Intent");
14868        }
14869
14870        if (DEBUG_SERVICE)
14871            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14872        synchronized(this) {
14873            final int callingPid = Binder.getCallingPid();
14874            final int callingUid = Binder.getCallingUid();
14875            final long origId = Binder.clearCallingIdentity();
14876            ComponentName res = mServices.startServiceLocked(caller, service,
14877                    resolvedType, callingPid, callingUid, userId);
14878            Binder.restoreCallingIdentity(origId);
14879            return res;
14880        }
14881    }
14882
14883    ComponentName startServiceInPackage(int uid,
14884            Intent service, String resolvedType, int userId) {
14885        synchronized(this) {
14886            if (DEBUG_SERVICE)
14887                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14888            final long origId = Binder.clearCallingIdentity();
14889            ComponentName res = mServices.startServiceLocked(null, service,
14890                    resolvedType, -1, uid, userId);
14891            Binder.restoreCallingIdentity(origId);
14892            return res;
14893        }
14894    }
14895
14896    @Override
14897    public int stopService(IApplicationThread caller, Intent service,
14898            String resolvedType, int userId) {
14899        enforceNotIsolatedCaller("stopService");
14900        // Refuse possible leaked file descriptors
14901        if (service != null && service.hasFileDescriptors() == true) {
14902            throw new IllegalArgumentException("File descriptors passed in Intent");
14903        }
14904
14905        synchronized(this) {
14906            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14907        }
14908    }
14909
14910    @Override
14911    public IBinder peekService(Intent service, String resolvedType) {
14912        enforceNotIsolatedCaller("peekService");
14913        // Refuse possible leaked file descriptors
14914        if (service != null && service.hasFileDescriptors() == true) {
14915            throw new IllegalArgumentException("File descriptors passed in Intent");
14916        }
14917        synchronized(this) {
14918            return mServices.peekServiceLocked(service, resolvedType);
14919        }
14920    }
14921
14922    @Override
14923    public boolean stopServiceToken(ComponentName className, IBinder token,
14924            int startId) {
14925        synchronized(this) {
14926            return mServices.stopServiceTokenLocked(className, token, startId);
14927        }
14928    }
14929
14930    @Override
14931    public void setServiceForeground(ComponentName className, IBinder token,
14932            int id, Notification notification, boolean removeNotification) {
14933        synchronized(this) {
14934            mServices.setServiceForegroundLocked(className, token, id, notification,
14935                    removeNotification);
14936        }
14937    }
14938
14939    @Override
14940    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14941            boolean requireFull, String name, String callerPackage) {
14942        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14943                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14944    }
14945
14946    int unsafeConvertIncomingUser(int userId) {
14947        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14948                ? mCurrentUserId : userId;
14949    }
14950
14951    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14952            int allowMode, String name, String callerPackage) {
14953        final int callingUserId = UserHandle.getUserId(callingUid);
14954        if (callingUserId == userId) {
14955            return userId;
14956        }
14957
14958        // Note that we may be accessing mCurrentUserId outside of a lock...
14959        // shouldn't be a big deal, if this is being called outside
14960        // of a locked context there is intrinsically a race with
14961        // the value the caller will receive and someone else changing it.
14962        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14963        // we will switch to the calling user if access to the current user fails.
14964        int targetUserId = unsafeConvertIncomingUser(userId);
14965
14966        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14967            final boolean allow;
14968            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14969                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14970                // If the caller has this permission, they always pass go.  And collect $200.
14971                allow = true;
14972            } else if (allowMode == ALLOW_FULL_ONLY) {
14973                // We require full access, sucks to be you.
14974                allow = false;
14975            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14976                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14977                // If the caller does not have either permission, they are always doomed.
14978                allow = false;
14979            } else if (allowMode == ALLOW_NON_FULL) {
14980                // We are blanket allowing non-full access, you lucky caller!
14981                allow = true;
14982            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14983                // We may or may not allow this depending on whether the two users are
14984                // in the same profile.
14985                synchronized (mUserProfileGroupIdsSelfLocked) {
14986                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14987                            UserInfo.NO_PROFILE_GROUP_ID);
14988                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14989                            UserInfo.NO_PROFILE_GROUP_ID);
14990                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14991                            && callingProfile == targetProfile;
14992                }
14993            } else {
14994                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14995            }
14996            if (!allow) {
14997                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14998                    // In this case, they would like to just execute as their
14999                    // owner user instead of failing.
15000                    targetUserId = callingUserId;
15001                } else {
15002                    StringBuilder builder = new StringBuilder(128);
15003                    builder.append("Permission Denial: ");
15004                    builder.append(name);
15005                    if (callerPackage != null) {
15006                        builder.append(" from ");
15007                        builder.append(callerPackage);
15008                    }
15009                    builder.append(" asks to run as user ");
15010                    builder.append(userId);
15011                    builder.append(" but is calling from user ");
15012                    builder.append(UserHandle.getUserId(callingUid));
15013                    builder.append("; this requires ");
15014                    builder.append(INTERACT_ACROSS_USERS_FULL);
15015                    if (allowMode != ALLOW_FULL_ONLY) {
15016                        builder.append(" or ");
15017                        builder.append(INTERACT_ACROSS_USERS);
15018                    }
15019                    String msg = builder.toString();
15020                    Slog.w(TAG, msg);
15021                    throw new SecurityException(msg);
15022                }
15023            }
15024        }
15025        if (!allowAll && targetUserId < 0) {
15026            throw new IllegalArgumentException(
15027                    "Call does not support special user #" + targetUserId);
15028        }
15029        // Check shell permission
15030        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15031            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15032                    targetUserId)) {
15033                throw new SecurityException("Shell does not have permission to access user "
15034                        + targetUserId + "\n " + Debug.getCallers(3));
15035            }
15036        }
15037        return targetUserId;
15038    }
15039
15040    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15041            String className, int flags) {
15042        boolean result = false;
15043        // For apps that don't have pre-defined UIDs, check for permission
15044        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15045            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15046                if (ActivityManager.checkUidPermission(
15047                        INTERACT_ACROSS_USERS,
15048                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15049                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15050                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15051                            + " requests FLAG_SINGLE_USER, but app does not hold "
15052                            + INTERACT_ACROSS_USERS;
15053                    Slog.w(TAG, msg);
15054                    throw new SecurityException(msg);
15055                }
15056                // Permission passed
15057                result = true;
15058            }
15059        } else if ("system".equals(componentProcessName)) {
15060            result = true;
15061        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15062            // Phone app and persistent apps are allowed to export singleuser providers.
15063            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15064                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15065        }
15066        if (DEBUG_MU) {
15067            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15068                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15069        }
15070        return result;
15071    }
15072
15073    /**
15074     * Checks to see if the caller is in the same app as the singleton
15075     * component, or the component is in a special app. It allows special apps
15076     * to export singleton components but prevents exporting singleton
15077     * components for regular apps.
15078     */
15079    boolean isValidSingletonCall(int callingUid, int componentUid) {
15080        int componentAppId = UserHandle.getAppId(componentUid);
15081        return UserHandle.isSameApp(callingUid, componentUid)
15082                || componentAppId == Process.SYSTEM_UID
15083                || componentAppId == Process.PHONE_UID
15084                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15085                        == PackageManager.PERMISSION_GRANTED;
15086    }
15087
15088    public int bindService(IApplicationThread caller, IBinder token,
15089            Intent service, String resolvedType,
15090            IServiceConnection connection, int flags, int userId) {
15091        enforceNotIsolatedCaller("bindService");
15092
15093        // Refuse possible leaked file descriptors
15094        if (service != null && service.hasFileDescriptors() == true) {
15095            throw new IllegalArgumentException("File descriptors passed in Intent");
15096        }
15097
15098        synchronized(this) {
15099            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15100                    connection, flags, userId);
15101        }
15102    }
15103
15104    public boolean unbindService(IServiceConnection connection) {
15105        synchronized (this) {
15106            return mServices.unbindServiceLocked(connection);
15107        }
15108    }
15109
15110    public void publishService(IBinder token, Intent intent, IBinder service) {
15111        // Refuse possible leaked file descriptors
15112        if (intent != null && intent.hasFileDescriptors() == true) {
15113            throw new IllegalArgumentException("File descriptors passed in Intent");
15114        }
15115
15116        synchronized(this) {
15117            if (!(token instanceof ServiceRecord)) {
15118                throw new IllegalArgumentException("Invalid service token");
15119            }
15120            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15121        }
15122    }
15123
15124    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15125        // Refuse possible leaked file descriptors
15126        if (intent != null && intent.hasFileDescriptors() == true) {
15127            throw new IllegalArgumentException("File descriptors passed in Intent");
15128        }
15129
15130        synchronized(this) {
15131            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15132        }
15133    }
15134
15135    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15136        synchronized(this) {
15137            if (!(token instanceof ServiceRecord)) {
15138                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15139                throw new IllegalArgumentException("Invalid service token");
15140            }
15141            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15142        }
15143    }
15144
15145    // =========================================================
15146    // BACKUP AND RESTORE
15147    // =========================================================
15148
15149    // Cause the target app to be launched if necessary and its backup agent
15150    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15151    // activity manager to announce its creation.
15152    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15153        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15154                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15155        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15156
15157        synchronized(this) {
15158            // !!! TODO: currently no check here that we're already bound
15159            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15160            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15161            synchronized (stats) {
15162                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15163            }
15164
15165            // Backup agent is now in use, its package can't be stopped.
15166            try {
15167                AppGlobals.getPackageManager().setPackageStoppedState(
15168                        app.packageName, false, UserHandle.getUserId(app.uid));
15169            } catch (RemoteException e) {
15170            } catch (IllegalArgumentException e) {
15171                Slog.w(TAG, "Failed trying to unstop package "
15172                        + app.packageName + ": " + e);
15173            }
15174
15175            BackupRecord r = new BackupRecord(ss, app, backupMode);
15176            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15177                    ? new ComponentName(app.packageName, app.backupAgentName)
15178                    : new ComponentName("android", "FullBackupAgent");
15179            // startProcessLocked() returns existing proc's record if it's already running
15180            ProcessRecord proc = startProcessLocked(app.processName, app,
15181                    false, 0, "backup", hostingName, false, false, false);
15182            if (proc == null) {
15183                Slog.e(TAG, "Unable to start backup agent process " + r);
15184                return false;
15185            }
15186
15187            r.app = proc;
15188            mBackupTarget = r;
15189            mBackupAppName = app.packageName;
15190
15191            // Try not to kill the process during backup
15192            updateOomAdjLocked(proc);
15193
15194            // If the process is already attached, schedule the creation of the backup agent now.
15195            // If it is not yet live, this will be done when it attaches to the framework.
15196            if (proc.thread != null) {
15197                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15198                try {
15199                    proc.thread.scheduleCreateBackupAgent(app,
15200                            compatibilityInfoForPackageLocked(app), backupMode);
15201                } catch (RemoteException e) {
15202                    // Will time out on the backup manager side
15203                }
15204            } else {
15205                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15206            }
15207            // Invariants: at this point, the target app process exists and the application
15208            // is either already running or in the process of coming up.  mBackupTarget and
15209            // mBackupAppName describe the app, so that when it binds back to the AM we
15210            // know that it's scheduled for a backup-agent operation.
15211        }
15212
15213        return true;
15214    }
15215
15216    @Override
15217    public void clearPendingBackup() {
15218        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15219        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15220
15221        synchronized (this) {
15222            mBackupTarget = null;
15223            mBackupAppName = null;
15224        }
15225    }
15226
15227    // A backup agent has just come up
15228    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15229        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15230                + " = " + agent);
15231
15232        synchronized(this) {
15233            if (!agentPackageName.equals(mBackupAppName)) {
15234                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15235                return;
15236            }
15237        }
15238
15239        long oldIdent = Binder.clearCallingIdentity();
15240        try {
15241            IBackupManager bm = IBackupManager.Stub.asInterface(
15242                    ServiceManager.getService(Context.BACKUP_SERVICE));
15243            bm.agentConnected(agentPackageName, agent);
15244        } catch (RemoteException e) {
15245            // can't happen; the backup manager service is local
15246        } catch (Exception e) {
15247            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15248            e.printStackTrace();
15249        } finally {
15250            Binder.restoreCallingIdentity(oldIdent);
15251        }
15252    }
15253
15254    // done with this agent
15255    public void unbindBackupAgent(ApplicationInfo appInfo) {
15256        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15257        if (appInfo == null) {
15258            Slog.w(TAG, "unbind backup agent for null app");
15259            return;
15260        }
15261
15262        synchronized(this) {
15263            try {
15264                if (mBackupAppName == null) {
15265                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15266                    return;
15267                }
15268
15269                if (!mBackupAppName.equals(appInfo.packageName)) {
15270                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15271                    return;
15272                }
15273
15274                // Not backing this app up any more; reset its OOM adjustment
15275                final ProcessRecord proc = mBackupTarget.app;
15276                updateOomAdjLocked(proc);
15277
15278                // If the app crashed during backup, 'thread' will be null here
15279                if (proc.thread != null) {
15280                    try {
15281                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15282                                compatibilityInfoForPackageLocked(appInfo));
15283                    } catch (Exception e) {
15284                        Slog.e(TAG, "Exception when unbinding backup agent:");
15285                        e.printStackTrace();
15286                    }
15287                }
15288            } finally {
15289                mBackupTarget = null;
15290                mBackupAppName = null;
15291            }
15292        }
15293    }
15294    // =========================================================
15295    // BROADCASTS
15296    // =========================================================
15297
15298    boolean isPendingBroadcastProcessLocked(int pid) {
15299        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15300                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15301    }
15302
15303    void skipPendingBroadcastLocked(int pid) {
15304            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15305            for (BroadcastQueue queue : mBroadcastQueues) {
15306                queue.skipPendingBroadcastLocked(pid);
15307            }
15308    }
15309
15310    // The app just attached; send any pending broadcasts that it should receive
15311    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15312        boolean didSomething = false;
15313        for (BroadcastQueue queue : mBroadcastQueues) {
15314            didSomething |= queue.sendPendingBroadcastsLocked(app);
15315        }
15316        return didSomething;
15317    }
15318
15319    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15320            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15321        enforceNotIsolatedCaller("registerReceiver");
15322        ArrayList<Intent> stickyIntents = null;
15323        ProcessRecord callerApp = null;
15324        int callingUid;
15325        int callingPid;
15326        synchronized(this) {
15327            if (caller != null) {
15328                callerApp = getRecordForAppLocked(caller);
15329                if (callerApp == null) {
15330                    throw new SecurityException(
15331                            "Unable to find app for caller " + caller
15332                            + " (pid=" + Binder.getCallingPid()
15333                            + ") when registering receiver " + receiver);
15334                }
15335                if (callerApp.info.uid != Process.SYSTEM_UID &&
15336                        !callerApp.pkgList.containsKey(callerPackage) &&
15337                        !"android".equals(callerPackage)) {
15338                    throw new SecurityException("Given caller package " + callerPackage
15339                            + " is not running in process " + callerApp);
15340                }
15341                callingUid = callerApp.info.uid;
15342                callingPid = callerApp.pid;
15343            } else {
15344                callerPackage = null;
15345                callingUid = Binder.getCallingUid();
15346                callingPid = Binder.getCallingPid();
15347            }
15348
15349            userId = handleIncomingUser(callingPid, callingUid, userId,
15350                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15351
15352            Iterator<String> actions = filter.actionsIterator();
15353            if (actions == null) {
15354                ArrayList<String> noAction = new ArrayList<String>(1);
15355                noAction.add(null);
15356                actions = noAction.iterator();
15357            }
15358
15359            // Collect stickies of users
15360            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15361            while (actions.hasNext()) {
15362                String action = actions.next();
15363                for (int id : userIds) {
15364                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15365                    if (stickies != null) {
15366                        ArrayList<Intent> intents = stickies.get(action);
15367                        if (intents != null) {
15368                            if (stickyIntents == null) {
15369                                stickyIntents = new ArrayList<Intent>();
15370                            }
15371                            stickyIntents.addAll(intents);
15372                        }
15373                    }
15374                }
15375            }
15376        }
15377
15378        ArrayList<Intent> allSticky = null;
15379        if (stickyIntents != null) {
15380            final ContentResolver resolver = mContext.getContentResolver();
15381            // Look for any matching sticky broadcasts...
15382            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15383                Intent intent = stickyIntents.get(i);
15384                // If intent has scheme "content", it will need to acccess
15385                // provider that needs to lock mProviderMap in ActivityThread
15386                // and also it may need to wait application response, so we
15387                // cannot lock ActivityManagerService here.
15388                if (filter.match(resolver, intent, true, TAG) >= 0) {
15389                    if (allSticky == null) {
15390                        allSticky = new ArrayList<Intent>();
15391                    }
15392                    allSticky.add(intent);
15393                }
15394            }
15395        }
15396
15397        // The first sticky in the list is returned directly back to the client.
15398        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15399        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15400        if (receiver == null) {
15401            return sticky;
15402        }
15403
15404        synchronized (this) {
15405            if (callerApp != null && callerApp.pid == 0) {
15406                // Caller already died
15407                return null;
15408            }
15409            ReceiverList rl
15410                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15411            if (rl == null) {
15412                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15413                        userId, receiver);
15414                if (rl.app != null) {
15415                    rl.app.receivers.add(rl);
15416                } else {
15417                    try {
15418                        receiver.asBinder().linkToDeath(rl, 0);
15419                    } catch (RemoteException e) {
15420                        return sticky;
15421                    }
15422                    rl.linkedToDeath = true;
15423                }
15424                mRegisteredReceivers.put(receiver.asBinder(), rl);
15425            } else if (rl.uid != callingUid) {
15426                throw new IllegalArgumentException(
15427                        "Receiver requested to register for uid " + callingUid
15428                        + " was previously registered for uid " + rl.uid);
15429            } else if (rl.pid != callingPid) {
15430                throw new IllegalArgumentException(
15431                        "Receiver requested to register for pid " + callingPid
15432                        + " was previously registered for pid " + rl.pid);
15433            } else if (rl.userId != userId) {
15434                throw new IllegalArgumentException(
15435                        "Receiver requested to register for user " + userId
15436                        + " was previously registered for user " + rl.userId);
15437            }
15438            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15439                    permission, callingUid, userId);
15440            rl.add(bf);
15441            if (!bf.debugCheck()) {
15442                Slog.w(TAG, "==> For Dynamic broadast");
15443            }
15444            mReceiverResolver.addFilter(bf);
15445
15446            // Enqueue broadcasts for all existing stickies that match
15447            // this filter.
15448            if (allSticky != null) {
15449                ArrayList receivers = new ArrayList();
15450                receivers.add(bf);
15451
15452                int N = allSticky.size();
15453                for (int i=0; i<N; i++) {
15454                    Intent intent = (Intent)allSticky.get(i);
15455                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15456                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15457                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15458                            null, null, false, true, true, -1);
15459                    queue.enqueueParallelBroadcastLocked(r);
15460                    queue.scheduleBroadcastsLocked();
15461                }
15462            }
15463
15464            return sticky;
15465        }
15466    }
15467
15468    public void unregisterReceiver(IIntentReceiver receiver) {
15469        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
15470
15471        final long origId = Binder.clearCallingIdentity();
15472        try {
15473            boolean doTrim = false;
15474
15475            synchronized(this) {
15476                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15477                if (rl != null) {
15478                    final BroadcastRecord r = rl.curBroadcast;
15479                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15480                        final boolean doNext = r.queue.finishReceiverLocked(
15481                                r, r.resultCode, r.resultData, r.resultExtras,
15482                                r.resultAbort, false);
15483                        if (doNext) {
15484                            doTrim = true;
15485                            r.queue.processNextBroadcast(false);
15486                        }
15487                    }
15488
15489                    if (rl.app != null) {
15490                        rl.app.receivers.remove(rl);
15491                    }
15492                    removeReceiverLocked(rl);
15493                    if (rl.linkedToDeath) {
15494                        rl.linkedToDeath = false;
15495                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15496                    }
15497                }
15498            }
15499
15500            // If we actually concluded any broadcasts, we might now be able
15501            // to trim the recipients' apps from our working set
15502            if (doTrim) {
15503                trimApplications();
15504                return;
15505            }
15506
15507        } finally {
15508            Binder.restoreCallingIdentity(origId);
15509        }
15510    }
15511
15512    void removeReceiverLocked(ReceiverList rl) {
15513        mRegisteredReceivers.remove(rl.receiver.asBinder());
15514        int N = rl.size();
15515        for (int i=0; i<N; i++) {
15516            mReceiverResolver.removeFilter(rl.get(i));
15517        }
15518    }
15519
15520    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15521        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15522            ProcessRecord r = mLruProcesses.get(i);
15523            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15524                try {
15525                    r.thread.dispatchPackageBroadcast(cmd, packages);
15526                } catch (RemoteException ex) {
15527                }
15528            }
15529        }
15530    }
15531
15532    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15533            int callingUid, int[] users) {
15534        List<ResolveInfo> receivers = null;
15535        try {
15536            HashSet<ComponentName> singleUserReceivers = null;
15537            boolean scannedFirstReceivers = false;
15538            for (int user : users) {
15539                // Skip users that have Shell restrictions
15540                if (callingUid == Process.SHELL_UID
15541                        && getUserManagerLocked().hasUserRestriction(
15542                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15543                    continue;
15544                }
15545                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15546                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15547                if (user != 0 && newReceivers != null) {
15548                    // If this is not the primary user, we need to check for
15549                    // any receivers that should be filtered out.
15550                    for (int i=0; i<newReceivers.size(); i++) {
15551                        ResolveInfo ri = newReceivers.get(i);
15552                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15553                            newReceivers.remove(i);
15554                            i--;
15555                        }
15556                    }
15557                }
15558                if (newReceivers != null && newReceivers.size() == 0) {
15559                    newReceivers = null;
15560                }
15561                if (receivers == null) {
15562                    receivers = newReceivers;
15563                } else if (newReceivers != null) {
15564                    // We need to concatenate the additional receivers
15565                    // found with what we have do far.  This would be easy,
15566                    // but we also need to de-dup any receivers that are
15567                    // singleUser.
15568                    if (!scannedFirstReceivers) {
15569                        // Collect any single user receivers we had already retrieved.
15570                        scannedFirstReceivers = true;
15571                        for (int i=0; i<receivers.size(); i++) {
15572                            ResolveInfo ri = receivers.get(i);
15573                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15574                                ComponentName cn = new ComponentName(
15575                                        ri.activityInfo.packageName, ri.activityInfo.name);
15576                                if (singleUserReceivers == null) {
15577                                    singleUserReceivers = new HashSet<ComponentName>();
15578                                }
15579                                singleUserReceivers.add(cn);
15580                            }
15581                        }
15582                    }
15583                    // Add the new results to the existing results, tracking
15584                    // and de-dupping single user receivers.
15585                    for (int i=0; i<newReceivers.size(); i++) {
15586                        ResolveInfo ri = newReceivers.get(i);
15587                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15588                            ComponentName cn = new ComponentName(
15589                                    ri.activityInfo.packageName, ri.activityInfo.name);
15590                            if (singleUserReceivers == null) {
15591                                singleUserReceivers = new HashSet<ComponentName>();
15592                            }
15593                            if (!singleUserReceivers.contains(cn)) {
15594                                singleUserReceivers.add(cn);
15595                                receivers.add(ri);
15596                            }
15597                        } else {
15598                            receivers.add(ri);
15599                        }
15600                    }
15601                }
15602            }
15603        } catch (RemoteException ex) {
15604            // pm is in same process, this will never happen.
15605        }
15606        return receivers;
15607    }
15608
15609    private final int broadcastIntentLocked(ProcessRecord callerApp,
15610            String callerPackage, Intent intent, String resolvedType,
15611            IIntentReceiver resultTo, int resultCode, String resultData,
15612            Bundle map, String requiredPermission, int appOp,
15613            boolean ordered, boolean sticky, int callingPid, int callingUid,
15614            int userId) {
15615        intent = new Intent(intent);
15616
15617        // By default broadcasts do not go to stopped apps.
15618        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15619
15620        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
15621                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15622                + " ordered=" + ordered + " userid=" + userId);
15623        if ((resultTo != null) && !ordered) {
15624            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15625        }
15626
15627        userId = handleIncomingUser(callingPid, callingUid, userId,
15628                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15629
15630        // Make sure that the user who is receiving this broadcast is running.
15631        // If not, we will just skip it. Make an exception for shutdown broadcasts
15632        // and upgrade steps.
15633
15634        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15635            if ((callingUid != Process.SYSTEM_UID
15636                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15637                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15638                Slog.w(TAG, "Skipping broadcast of " + intent
15639                        + ": user " + userId + " is stopped");
15640                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15641            }
15642        }
15643
15644        /*
15645         * Prevent non-system code (defined here to be non-persistent
15646         * processes) from sending protected broadcasts.
15647         */
15648        int callingAppId = UserHandle.getAppId(callingUid);
15649        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15650            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15651            || callingAppId == Process.NFC_UID || callingUid == 0) {
15652            // Always okay.
15653        } else if (callerApp == null || !callerApp.persistent) {
15654            try {
15655                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15656                        intent.getAction())) {
15657                    String msg = "Permission Denial: not allowed to send broadcast "
15658                            + intent.getAction() + " from pid="
15659                            + callingPid + ", uid=" + callingUid;
15660                    Slog.w(TAG, msg);
15661                    throw new SecurityException(msg);
15662                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15663                    // Special case for compatibility: we don't want apps to send this,
15664                    // but historically it has not been protected and apps may be using it
15665                    // to poke their own app widget.  So, instead of making it protected,
15666                    // just limit it to the caller.
15667                    if (callerApp == null) {
15668                        String msg = "Permission Denial: not allowed to send broadcast "
15669                                + intent.getAction() + " from unknown caller.";
15670                        Slog.w(TAG, msg);
15671                        throw new SecurityException(msg);
15672                    } else if (intent.getComponent() != null) {
15673                        // They are good enough to send to an explicit component...  verify
15674                        // it is being sent to the calling app.
15675                        if (!intent.getComponent().getPackageName().equals(
15676                                callerApp.info.packageName)) {
15677                            String msg = "Permission Denial: not allowed to send broadcast "
15678                                    + intent.getAction() + " to "
15679                                    + intent.getComponent().getPackageName() + " from "
15680                                    + callerApp.info.packageName;
15681                            Slog.w(TAG, msg);
15682                            throw new SecurityException(msg);
15683                        }
15684                    } else {
15685                        // Limit broadcast to their own package.
15686                        intent.setPackage(callerApp.info.packageName);
15687                    }
15688                }
15689            } catch (RemoteException e) {
15690                Slog.w(TAG, "Remote exception", e);
15691                return ActivityManager.BROADCAST_SUCCESS;
15692            }
15693        }
15694
15695        final String action = intent.getAction();
15696        if (action != null) {
15697            switch (action) {
15698                case Intent.ACTION_UID_REMOVED:
15699                case Intent.ACTION_PACKAGE_REMOVED:
15700                case Intent.ACTION_PACKAGE_CHANGED:
15701                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15702                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15703                    // Handle special intents: if this broadcast is from the package
15704                    // manager about a package being removed, we need to remove all of
15705                    // its activities from the history stack.
15706                    if (checkComponentPermission(
15707                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15708                            callingPid, callingUid, -1, true)
15709                            != PackageManager.PERMISSION_GRANTED) {
15710                        String msg = "Permission Denial: " + intent.getAction()
15711                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15712                                + ", uid=" + callingUid + ")"
15713                                + " requires "
15714                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15715                        Slog.w(TAG, msg);
15716                        throw new SecurityException(msg);
15717                    }
15718                    switch (action) {
15719                        case Intent.ACTION_UID_REMOVED:
15720                            final Bundle intentExtras = intent.getExtras();
15721                            final int uid = intentExtras != null
15722                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15723                            if (uid >= 0) {
15724                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15725                                synchronized (bs) {
15726                                    bs.removeUidStatsLocked(uid);
15727                                }
15728                                mAppOpsService.uidRemoved(uid);
15729                            }
15730                            break;
15731                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15732                            // If resources are unavailable just force stop all those packages
15733                            // and flush the attribute cache as well.
15734                            String list[] =
15735                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15736                            if (list != null && list.length > 0) {
15737                                for (int i = 0; i < list.length; i++) {
15738                                    forceStopPackageLocked(list[i], -1, false, true, true,
15739                                            false, false, userId, "storage unmount");
15740                                }
15741                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15742                                sendPackageBroadcastLocked(
15743                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15744                                        userId);
15745                            }
15746                            break;
15747                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15748                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15749                            break;
15750                        case Intent.ACTION_PACKAGE_REMOVED:
15751                        case Intent.ACTION_PACKAGE_CHANGED:
15752                            Uri data = intent.getData();
15753                            String ssp;
15754                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15755                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15756                                boolean fullUninstall = removed &&
15757                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15758                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15759                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15760                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15761                                            false, true, true, false, fullUninstall, userId,
15762                                            removed ? "pkg removed" : "pkg changed");
15763                                }
15764                                if (removed) {
15765                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15766                                            new String[] {ssp}, userId);
15767                                    if (fullUninstall) {
15768                                        mAppOpsService.packageRemoved(
15769                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15770
15771                                        // Remove all permissions granted from/to this package
15772                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15773
15774                                        removeTasksByPackageNameLocked(ssp, userId);
15775                                        if (userId == UserHandle.USER_OWNER) {
15776                                            mTaskPersister.removeFromPackageCache(ssp);
15777                                        }
15778                                    }
15779                                } else {
15780                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15781                                    if (userId == UserHandle.USER_OWNER) {
15782                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15783                                    }
15784                                }
15785                            }
15786                            break;
15787                    }
15788                    break;
15789                case Intent.ACTION_PACKAGE_ADDED:
15790                    // Special case for adding a package: by default turn on compatibility mode.
15791                    Uri data = intent.getData();
15792                    String ssp;
15793                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15794                        final boolean replacing =
15795                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15796                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15797
15798                        if (replacing) {
15799                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15800                        }
15801                        if (userId == UserHandle.USER_OWNER) {
15802                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15803                        }
15804                    }
15805                    break;
15806                case Intent.ACTION_TIMEZONE_CHANGED:
15807                    // If this is the time zone changed action, queue up a message that will reset
15808                    // the timezone of all currently running processes. This message will get
15809                    // queued up before the broadcast happens.
15810                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15811                    break;
15812                case Intent.ACTION_TIME_CHANGED:
15813                    // If the user set the time, let all running processes know.
15814                    final int is24Hour =
15815                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15816                                    : 0;
15817                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15818                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15819                    synchronized (stats) {
15820                        stats.noteCurrentTimeChangedLocked();
15821                    }
15822                    break;
15823                case Intent.ACTION_CLEAR_DNS_CACHE:
15824                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15825                    break;
15826                case Proxy.PROXY_CHANGE_ACTION:
15827                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15828                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15829                    break;
15830            }
15831        }
15832
15833        // Add to the sticky list if requested.
15834        if (sticky) {
15835            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15836                    callingPid, callingUid)
15837                    != PackageManager.PERMISSION_GRANTED) {
15838                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15839                        + callingPid + ", uid=" + callingUid
15840                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15841                Slog.w(TAG, msg);
15842                throw new SecurityException(msg);
15843            }
15844            if (requiredPermission != null) {
15845                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15846                        + " and enforce permission " + requiredPermission);
15847                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15848            }
15849            if (intent.getComponent() != null) {
15850                throw new SecurityException(
15851                        "Sticky broadcasts can't target a specific component");
15852            }
15853            // We use userId directly here, since the "all" target is maintained
15854            // as a separate set of sticky broadcasts.
15855            if (userId != UserHandle.USER_ALL) {
15856                // But first, if this is not a broadcast to all users, then
15857                // make sure it doesn't conflict with an existing broadcast to
15858                // all users.
15859                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15860                        UserHandle.USER_ALL);
15861                if (stickies != null) {
15862                    ArrayList<Intent> list = stickies.get(intent.getAction());
15863                    if (list != null) {
15864                        int N = list.size();
15865                        int i;
15866                        for (i=0; i<N; i++) {
15867                            if (intent.filterEquals(list.get(i))) {
15868                                throw new IllegalArgumentException(
15869                                        "Sticky broadcast " + intent + " for user "
15870                                        + userId + " conflicts with existing global broadcast");
15871                            }
15872                        }
15873                    }
15874                }
15875            }
15876            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15877            if (stickies == null) {
15878                stickies = new ArrayMap<String, ArrayList<Intent>>();
15879                mStickyBroadcasts.put(userId, stickies);
15880            }
15881            ArrayList<Intent> list = stickies.get(intent.getAction());
15882            if (list == null) {
15883                list = new ArrayList<Intent>();
15884                stickies.put(intent.getAction(), list);
15885            }
15886            int N = list.size();
15887            int i;
15888            for (i=0; i<N; i++) {
15889                if (intent.filterEquals(list.get(i))) {
15890                    // This sticky already exists, replace it.
15891                    list.set(i, new Intent(intent));
15892                    break;
15893                }
15894            }
15895            if (i >= N) {
15896                list.add(new Intent(intent));
15897            }
15898        }
15899
15900        int[] users;
15901        if (userId == UserHandle.USER_ALL) {
15902            // Caller wants broadcast to go to all started users.
15903            users = mStartedUserArray;
15904        } else {
15905            // Caller wants broadcast to go to one specific user.
15906            users = new int[] {userId};
15907        }
15908
15909        // Figure out who all will receive this broadcast.
15910        List receivers = null;
15911        List<BroadcastFilter> registeredReceivers = null;
15912        // Need to resolve the intent to interested receivers...
15913        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15914                 == 0) {
15915            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15916        }
15917        if (intent.getComponent() == null) {
15918            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15919                // Query one target user at a time, excluding shell-restricted users
15920                UserManagerService ums = getUserManagerLocked();
15921                for (int i = 0; i < users.length; i++) {
15922                    if (ums.hasUserRestriction(
15923                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15924                        continue;
15925                    }
15926                    List<BroadcastFilter> registeredReceiversForUser =
15927                            mReceiverResolver.queryIntent(intent,
15928                                    resolvedType, false, users[i]);
15929                    if (registeredReceivers == null) {
15930                        registeredReceivers = registeredReceiversForUser;
15931                    } else if (registeredReceiversForUser != null) {
15932                        registeredReceivers.addAll(registeredReceiversForUser);
15933                    }
15934                }
15935            } else {
15936                registeredReceivers = mReceiverResolver.queryIntent(intent,
15937                        resolvedType, false, userId);
15938            }
15939        }
15940
15941        final boolean replacePending =
15942                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15943
15944        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
15945                + " replacePending=" + replacePending);
15946
15947        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15948        if (!ordered && NR > 0) {
15949            // If we are not serializing this broadcast, then send the
15950            // registered receivers separately so they don't wait for the
15951            // components to be launched.
15952            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15953            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15954                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15955                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15956                    ordered, sticky, false, userId);
15957            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
15958            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15959            if (!replaced) {
15960                queue.enqueueParallelBroadcastLocked(r);
15961                queue.scheduleBroadcastsLocked();
15962            }
15963            registeredReceivers = null;
15964            NR = 0;
15965        }
15966
15967        // Merge into one list.
15968        int ir = 0;
15969        if (receivers != null) {
15970            // A special case for PACKAGE_ADDED: do not allow the package
15971            // being added to see this broadcast.  This prevents them from
15972            // using this as a back door to get run as soon as they are
15973            // installed.  Maybe in the future we want to have a special install
15974            // broadcast or such for apps, but we'd like to deliberately make
15975            // this decision.
15976            String skipPackages[] = null;
15977            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15978                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15979                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15980                Uri data = intent.getData();
15981                if (data != null) {
15982                    String pkgName = data.getSchemeSpecificPart();
15983                    if (pkgName != null) {
15984                        skipPackages = new String[] { pkgName };
15985                    }
15986                }
15987            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15988                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15989            }
15990            if (skipPackages != null && (skipPackages.length > 0)) {
15991                for (String skipPackage : skipPackages) {
15992                    if (skipPackage != null) {
15993                        int NT = receivers.size();
15994                        for (int it=0; it<NT; it++) {
15995                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15996                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15997                                receivers.remove(it);
15998                                it--;
15999                                NT--;
16000                            }
16001                        }
16002                    }
16003                }
16004            }
16005
16006            int NT = receivers != null ? receivers.size() : 0;
16007            int it = 0;
16008            ResolveInfo curt = null;
16009            BroadcastFilter curr = null;
16010            while (it < NT && ir < NR) {
16011                if (curt == null) {
16012                    curt = (ResolveInfo)receivers.get(it);
16013                }
16014                if (curr == null) {
16015                    curr = registeredReceivers.get(ir);
16016                }
16017                if (curr.getPriority() >= curt.priority) {
16018                    // Insert this broadcast record into the final list.
16019                    receivers.add(it, curr);
16020                    ir++;
16021                    curr = null;
16022                    it++;
16023                    NT++;
16024                } else {
16025                    // Skip to the next ResolveInfo in the final list.
16026                    it++;
16027                    curt = null;
16028                }
16029            }
16030        }
16031        while (ir < NR) {
16032            if (receivers == null) {
16033                receivers = new ArrayList();
16034            }
16035            receivers.add(registeredReceivers.get(ir));
16036            ir++;
16037        }
16038
16039        if ((receivers != null && receivers.size() > 0)
16040                || resultTo != null) {
16041            BroadcastQueue queue = broadcastQueueForIntent(intent);
16042            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16043                    callerPackage, callingPid, callingUid, resolvedType,
16044                    requiredPermission, appOp, receivers, resultTo, resultCode,
16045                    resultData, map, ordered, sticky, false, userId);
16046
16047            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16048                    + ": prev had " + queue.mOrderedBroadcasts.size());
16049            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16050                    "Enqueueing broadcast " + r.intent.getAction());
16051
16052            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16053            if (!replaced) {
16054                queue.enqueueOrderedBroadcastLocked(r);
16055                queue.scheduleBroadcastsLocked();
16056            }
16057        }
16058
16059        return ActivityManager.BROADCAST_SUCCESS;
16060    }
16061
16062    final Intent verifyBroadcastLocked(Intent intent) {
16063        // Refuse possible leaked file descriptors
16064        if (intent != null && intent.hasFileDescriptors() == true) {
16065            throw new IllegalArgumentException("File descriptors passed in Intent");
16066        }
16067
16068        int flags = intent.getFlags();
16069
16070        if (!mProcessesReady) {
16071            // if the caller really truly claims to know what they're doing, go
16072            // ahead and allow the broadcast without launching any receivers
16073            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16074                intent = new Intent(intent);
16075                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16076            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16077                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16078                        + " before boot completion");
16079                throw new IllegalStateException("Cannot broadcast before boot completed");
16080            }
16081        }
16082
16083        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16084            throw new IllegalArgumentException(
16085                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16086        }
16087
16088        return intent;
16089    }
16090
16091    public final int broadcastIntent(IApplicationThread caller,
16092            Intent intent, String resolvedType, IIntentReceiver resultTo,
16093            int resultCode, String resultData, Bundle map,
16094            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16095        enforceNotIsolatedCaller("broadcastIntent");
16096        synchronized(this) {
16097            intent = verifyBroadcastLocked(intent);
16098
16099            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16100            final int callingPid = Binder.getCallingPid();
16101            final int callingUid = Binder.getCallingUid();
16102            final long origId = Binder.clearCallingIdentity();
16103            int res = broadcastIntentLocked(callerApp,
16104                    callerApp != null ? callerApp.info.packageName : null,
16105                    intent, resolvedType, resultTo,
16106                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16107                    callingPid, callingUid, userId);
16108            Binder.restoreCallingIdentity(origId);
16109            return res;
16110        }
16111    }
16112
16113    int broadcastIntentInPackage(String packageName, int uid,
16114            Intent intent, String resolvedType, IIntentReceiver resultTo,
16115            int resultCode, String resultData, Bundle map,
16116            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16117        synchronized(this) {
16118            intent = verifyBroadcastLocked(intent);
16119
16120            final long origId = Binder.clearCallingIdentity();
16121            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16122                    resultTo, resultCode, resultData, map, requiredPermission,
16123                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16124            Binder.restoreCallingIdentity(origId);
16125            return res;
16126        }
16127    }
16128
16129    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16130        // Refuse possible leaked file descriptors
16131        if (intent != null && intent.hasFileDescriptors() == true) {
16132            throw new IllegalArgumentException("File descriptors passed in Intent");
16133        }
16134
16135        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16136                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16137
16138        synchronized(this) {
16139            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16140                    != PackageManager.PERMISSION_GRANTED) {
16141                String msg = "Permission Denial: unbroadcastIntent() from pid="
16142                        + Binder.getCallingPid()
16143                        + ", uid=" + Binder.getCallingUid()
16144                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16145                Slog.w(TAG, msg);
16146                throw new SecurityException(msg);
16147            }
16148            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16149            if (stickies != null) {
16150                ArrayList<Intent> list = stickies.get(intent.getAction());
16151                if (list != null) {
16152                    int N = list.size();
16153                    int i;
16154                    for (i=0; i<N; i++) {
16155                        if (intent.filterEquals(list.get(i))) {
16156                            list.remove(i);
16157                            break;
16158                        }
16159                    }
16160                    if (list.size() <= 0) {
16161                        stickies.remove(intent.getAction());
16162                    }
16163                }
16164                if (stickies.size() <= 0) {
16165                    mStickyBroadcasts.remove(userId);
16166                }
16167            }
16168        }
16169    }
16170
16171    void backgroundServicesFinishedLocked(int userId) {
16172        for (BroadcastQueue queue : mBroadcastQueues) {
16173            queue.backgroundServicesFinishedLocked(userId);
16174        }
16175    }
16176
16177    public void finishReceiver(IBinder who, int resultCode, String resultData,
16178            Bundle resultExtras, boolean resultAbort, int flags) {
16179        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16180
16181        // Refuse possible leaked file descriptors
16182        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16183            throw new IllegalArgumentException("File descriptors passed in Bundle");
16184        }
16185
16186        final long origId = Binder.clearCallingIdentity();
16187        try {
16188            boolean doNext = false;
16189            BroadcastRecord r;
16190
16191            synchronized(this) {
16192                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16193                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16194                r = queue.getMatchingOrderedReceiver(who);
16195                if (r != null) {
16196                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16197                        resultData, resultExtras, resultAbort, true);
16198                }
16199            }
16200
16201            if (doNext) {
16202                r.queue.processNextBroadcast(false);
16203            }
16204            trimApplications();
16205        } finally {
16206            Binder.restoreCallingIdentity(origId);
16207        }
16208    }
16209
16210    // =========================================================
16211    // INSTRUMENTATION
16212    // =========================================================
16213
16214    public boolean startInstrumentation(ComponentName className,
16215            String profileFile, int flags, Bundle arguments,
16216            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16217            int userId, String abiOverride) {
16218        enforceNotIsolatedCaller("startInstrumentation");
16219        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16220                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16221        // Refuse possible leaked file descriptors
16222        if (arguments != null && arguments.hasFileDescriptors()) {
16223            throw new IllegalArgumentException("File descriptors passed in Bundle");
16224        }
16225
16226        synchronized(this) {
16227            InstrumentationInfo ii = null;
16228            ApplicationInfo ai = null;
16229            try {
16230                ii = mContext.getPackageManager().getInstrumentationInfo(
16231                    className, STOCK_PM_FLAGS);
16232                ai = AppGlobals.getPackageManager().getApplicationInfo(
16233                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16234            } catch (PackageManager.NameNotFoundException e) {
16235            } catch (RemoteException e) {
16236            }
16237            if (ii == null) {
16238                reportStartInstrumentationFailure(watcher, className,
16239                        "Unable to find instrumentation info for: " + className);
16240                return false;
16241            }
16242            if (ai == null) {
16243                reportStartInstrumentationFailure(watcher, className,
16244                        "Unable to find instrumentation target package: " + ii.targetPackage);
16245                return false;
16246            }
16247
16248            int match = mContext.getPackageManager().checkSignatures(
16249                    ii.targetPackage, ii.packageName);
16250            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16251                String msg = "Permission Denial: starting instrumentation "
16252                        + className + " from pid="
16253                        + Binder.getCallingPid()
16254                        + ", uid=" + Binder.getCallingPid()
16255                        + " not allowed because package " + ii.packageName
16256                        + " does not have a signature matching the target "
16257                        + ii.targetPackage;
16258                reportStartInstrumentationFailure(watcher, className, msg);
16259                throw new SecurityException(msg);
16260            }
16261
16262            final long origId = Binder.clearCallingIdentity();
16263            // Instrumentation can kill and relaunch even persistent processes
16264            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16265                    "start instr");
16266            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16267            app.instrumentationClass = className;
16268            app.instrumentationInfo = ai;
16269            app.instrumentationProfileFile = profileFile;
16270            app.instrumentationArguments = arguments;
16271            app.instrumentationWatcher = watcher;
16272            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16273            app.instrumentationResultClass = className;
16274            Binder.restoreCallingIdentity(origId);
16275        }
16276
16277        return true;
16278    }
16279
16280    /**
16281     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16282     * error to the logs, but if somebody is watching, send the report there too.  This enables
16283     * the "am" command to report errors with more information.
16284     *
16285     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16286     * @param cn The component name of the instrumentation.
16287     * @param report The error report.
16288     */
16289    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16290            ComponentName cn, String report) {
16291        Slog.w(TAG, report);
16292        try {
16293            if (watcher != null) {
16294                Bundle results = new Bundle();
16295                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16296                results.putString("Error", report);
16297                watcher.instrumentationStatus(cn, -1, results);
16298            }
16299        } catch (RemoteException e) {
16300            Slog.w(TAG, e);
16301        }
16302    }
16303
16304    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16305        if (app.instrumentationWatcher != null) {
16306            try {
16307                // NOTE:  IInstrumentationWatcher *must* be oneway here
16308                app.instrumentationWatcher.instrumentationFinished(
16309                    app.instrumentationClass,
16310                    resultCode,
16311                    results);
16312            } catch (RemoteException e) {
16313            }
16314        }
16315        if (app.instrumentationUiAutomationConnection != null) {
16316            try {
16317                app.instrumentationUiAutomationConnection.shutdown();
16318            } catch (RemoteException re) {
16319                /* ignore */
16320            }
16321            // Only a UiAutomation can set this flag and now that
16322            // it is finished we make sure it is reset to its default.
16323            mUserIsMonkey = false;
16324        }
16325        app.instrumentationWatcher = null;
16326        app.instrumentationUiAutomationConnection = null;
16327        app.instrumentationClass = null;
16328        app.instrumentationInfo = null;
16329        app.instrumentationProfileFile = null;
16330        app.instrumentationArguments = null;
16331
16332        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16333                "finished inst");
16334    }
16335
16336    public void finishInstrumentation(IApplicationThread target,
16337            int resultCode, Bundle results) {
16338        int userId = UserHandle.getCallingUserId();
16339        // Refuse possible leaked file descriptors
16340        if (results != null && results.hasFileDescriptors()) {
16341            throw new IllegalArgumentException("File descriptors passed in Intent");
16342        }
16343
16344        synchronized(this) {
16345            ProcessRecord app = getRecordForAppLocked(target);
16346            if (app == null) {
16347                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16348                return;
16349            }
16350            final long origId = Binder.clearCallingIdentity();
16351            finishInstrumentationLocked(app, resultCode, results);
16352            Binder.restoreCallingIdentity(origId);
16353        }
16354    }
16355
16356    // =========================================================
16357    // CONFIGURATION
16358    // =========================================================
16359
16360    public ConfigurationInfo getDeviceConfigurationInfo() {
16361        ConfigurationInfo config = new ConfigurationInfo();
16362        synchronized (this) {
16363            config.reqTouchScreen = mConfiguration.touchscreen;
16364            config.reqKeyboardType = mConfiguration.keyboard;
16365            config.reqNavigation = mConfiguration.navigation;
16366            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16367                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16368                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16369            }
16370            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16371                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16372                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16373            }
16374            config.reqGlEsVersion = GL_ES_VERSION;
16375        }
16376        return config;
16377    }
16378
16379    ActivityStack getFocusedStack() {
16380        return mStackSupervisor.getFocusedStack();
16381    }
16382
16383    @Override
16384    public int getFocusedStackId() throws RemoteException {
16385        ActivityStack focusedStack = getFocusedStack();
16386        if (focusedStack != null) {
16387            return focusedStack.getStackId();
16388        }
16389        return -1;
16390    }
16391
16392    public Configuration getConfiguration() {
16393        Configuration ci;
16394        synchronized(this) {
16395            ci = new Configuration(mConfiguration);
16396            ci.userSetLocale = false;
16397        }
16398        return ci;
16399    }
16400
16401    public void updatePersistentConfiguration(Configuration values) {
16402        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16403                "updateConfiguration()");
16404        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16405                "updateConfiguration()");
16406        if (values == null) {
16407            throw new NullPointerException("Configuration must not be null");
16408        }
16409
16410        synchronized(this) {
16411            final long origId = Binder.clearCallingIdentity();
16412            updateConfigurationLocked(values, null, true, false);
16413            Binder.restoreCallingIdentity(origId);
16414        }
16415    }
16416
16417    public void updateConfiguration(Configuration values) {
16418        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16419                "updateConfiguration()");
16420
16421        synchronized(this) {
16422            if (values == null && mWindowManager != null) {
16423                // sentinel: fetch the current configuration from the window manager
16424                values = mWindowManager.computeNewConfiguration();
16425            }
16426
16427            if (mWindowManager != null) {
16428                mProcessList.applyDisplaySize(mWindowManager);
16429            }
16430
16431            final long origId = Binder.clearCallingIdentity();
16432            if (values != null) {
16433                Settings.System.clearConfiguration(values);
16434            }
16435            updateConfigurationLocked(values, null, false, false);
16436            Binder.restoreCallingIdentity(origId);
16437        }
16438    }
16439
16440    /**
16441     * Do either or both things: (1) change the current configuration, and (2)
16442     * make sure the given activity is running with the (now) current
16443     * configuration.  Returns true if the activity has been left running, or
16444     * false if <var>starting</var> is being destroyed to match the new
16445     * configuration.
16446     * @param persistent TODO
16447     */
16448    boolean updateConfigurationLocked(Configuration values,
16449            ActivityRecord starting, boolean persistent, boolean initLocale) {
16450        int changes = 0;
16451
16452        if (values != null) {
16453            Configuration newConfig = new Configuration(mConfiguration);
16454            changes = newConfig.updateFrom(values);
16455            if (changes != 0) {
16456                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16457                    Slog.i(TAG, "Updating configuration to: " + values);
16458                }
16459
16460                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16461
16462                if (!initLocale && values.locale != null && values.userSetLocale) {
16463                    final String languageTag = values.locale.toLanguageTag();
16464                    SystemProperties.set("persist.sys.locale", languageTag);
16465                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16466                            values.locale));
16467                }
16468
16469                mConfigurationSeq++;
16470                if (mConfigurationSeq <= 0) {
16471                    mConfigurationSeq = 1;
16472                }
16473                newConfig.seq = mConfigurationSeq;
16474                mConfiguration = newConfig;
16475                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16476                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16477                //mUsageStatsService.noteStartConfig(newConfig);
16478
16479                final Configuration configCopy = new Configuration(mConfiguration);
16480
16481                // TODO: If our config changes, should we auto dismiss any currently
16482                // showing dialogs?
16483                mShowDialogs = shouldShowDialogs(newConfig);
16484
16485                AttributeCache ac = AttributeCache.instance();
16486                if (ac != null) {
16487                    ac.updateConfiguration(configCopy);
16488                }
16489
16490                // Make sure all resources in our process are updated
16491                // right now, so that anyone who is going to retrieve
16492                // resource values after we return will be sure to get
16493                // the new ones.  This is especially important during
16494                // boot, where the first config change needs to guarantee
16495                // all resources have that config before following boot
16496                // code is executed.
16497                mSystemThread.applyConfigurationToResources(configCopy);
16498
16499                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16500                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16501                    msg.obj = new Configuration(configCopy);
16502                    mHandler.sendMessage(msg);
16503                }
16504
16505                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16506                    ProcessRecord app = mLruProcesses.get(i);
16507                    try {
16508                        if (app.thread != null) {
16509                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16510                                    + app.processName + " new config " + mConfiguration);
16511                            app.thread.scheduleConfigurationChanged(configCopy);
16512                        }
16513                    } catch (Exception e) {
16514                    }
16515                }
16516                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16517                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16518                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16519                        | Intent.FLAG_RECEIVER_FOREGROUND);
16520                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16521                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16522                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16523                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16524                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16525                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16526                    broadcastIntentLocked(null, null, intent,
16527                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16528                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16529                }
16530            }
16531        }
16532
16533        boolean kept = true;
16534        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16535        // mainStack is null during startup.
16536        if (mainStack != null) {
16537            if (changes != 0 && starting == null) {
16538                // If the configuration changed, and the caller is not already
16539                // in the process of starting an activity, then find the top
16540                // activity to check if its configuration needs to change.
16541                starting = mainStack.topRunningActivityLocked(null);
16542            }
16543
16544            if (starting != null) {
16545                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16546                // And we need to make sure at this point that all other activities
16547                // are made visible with the correct configuration.
16548                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16549            }
16550        }
16551
16552        if (values != null && mWindowManager != null) {
16553            mWindowManager.setNewConfiguration(mConfiguration);
16554        }
16555
16556        return kept;
16557    }
16558
16559    /**
16560     * Decide based on the configuration whether we should shouw the ANR,
16561     * crash, etc dialogs.  The idea is that if there is no affordnace to
16562     * press the on-screen buttons, we shouldn't show the dialog.
16563     *
16564     * A thought: SystemUI might also want to get told about this, the Power
16565     * dialog / global actions also might want different behaviors.
16566     */
16567    private static final boolean shouldShowDialogs(Configuration config) {
16568        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16569                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16570                && config.navigation == Configuration.NAVIGATION_NONAV);
16571    }
16572
16573    @Override
16574    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16575        synchronized (this) {
16576            ActivityRecord srec = ActivityRecord.forToken(token);
16577            if (srec.task != null && srec.task.stack != null) {
16578                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16579            }
16580        }
16581        return false;
16582    }
16583
16584    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16585            Intent resultData) {
16586
16587        synchronized (this) {
16588            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16589            if (stack != null) {
16590                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16591            }
16592            return false;
16593        }
16594    }
16595
16596    public int getLaunchedFromUid(IBinder activityToken) {
16597        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16598        if (srec == null) {
16599            return -1;
16600        }
16601        return srec.launchedFromUid;
16602    }
16603
16604    public String getLaunchedFromPackage(IBinder activityToken) {
16605        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16606        if (srec == null) {
16607            return null;
16608        }
16609        return srec.launchedFromPackage;
16610    }
16611
16612    // =========================================================
16613    // LIFETIME MANAGEMENT
16614    // =========================================================
16615
16616    // Returns which broadcast queue the app is the current [or imminent] receiver
16617    // on, or 'null' if the app is not an active broadcast recipient.
16618    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16619        BroadcastRecord r = app.curReceiver;
16620        if (r != null) {
16621            return r.queue;
16622        }
16623
16624        // It's not the current receiver, but it might be starting up to become one
16625        synchronized (this) {
16626            for (BroadcastQueue queue : mBroadcastQueues) {
16627                r = queue.mPendingBroadcast;
16628                if (r != null && r.curApp == app) {
16629                    // found it; report which queue it's in
16630                    return queue;
16631                }
16632            }
16633        }
16634
16635        return null;
16636    }
16637
16638    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16639            ComponentName targetComponent, String targetProcess) {
16640        if (!mTrackingAssociations) {
16641            return null;
16642        }
16643        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16644                = mAssociations.get(targetUid);
16645        if (components == null) {
16646            components = new ArrayMap<>();
16647            mAssociations.put(targetUid, components);
16648        }
16649        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16650        if (sourceUids == null) {
16651            sourceUids = new SparseArray<>();
16652            components.put(targetComponent, sourceUids);
16653        }
16654        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16655        if (sourceProcesses == null) {
16656            sourceProcesses = new ArrayMap<>();
16657            sourceUids.put(sourceUid, sourceProcesses);
16658        }
16659        Association ass = sourceProcesses.get(sourceProcess);
16660        if (ass == null) {
16661            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16662                    targetProcess);
16663            sourceProcesses.put(sourceProcess, ass);
16664        }
16665        ass.mCount++;
16666        ass.mNesting++;
16667        if (ass.mNesting == 1) {
16668            ass.mStartTime = SystemClock.uptimeMillis();
16669        }
16670        return ass;
16671    }
16672
16673    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16674            ComponentName targetComponent) {
16675        if (!mTrackingAssociations) {
16676            return;
16677        }
16678        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16679                = mAssociations.get(targetUid);
16680        if (components == null) {
16681            return;
16682        }
16683        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16684        if (sourceUids == null) {
16685            return;
16686        }
16687        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16688        if (sourceProcesses == null) {
16689            return;
16690        }
16691        Association ass = sourceProcesses.get(sourceProcess);
16692        if (ass == null || ass.mNesting <= 0) {
16693            return;
16694        }
16695        ass.mNesting--;
16696        if (ass.mNesting == 0) {
16697            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16698        }
16699    }
16700
16701    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16702            boolean doingAll, long now) {
16703        if (mAdjSeq == app.adjSeq) {
16704            // This adjustment has already been computed.
16705            return app.curRawAdj;
16706        }
16707
16708        if (app.thread == null) {
16709            app.adjSeq = mAdjSeq;
16710            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16711            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16712            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16713        }
16714
16715        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16716        app.adjSource = null;
16717        app.adjTarget = null;
16718        app.empty = false;
16719        app.cached = false;
16720
16721        final int activitiesSize = app.activities.size();
16722
16723        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16724            // The max adjustment doesn't allow this app to be anything
16725            // below foreground, so it is not worth doing work for it.
16726            app.adjType = "fixed";
16727            app.adjSeq = mAdjSeq;
16728            app.curRawAdj = app.maxAdj;
16729            app.foregroundActivities = false;
16730            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16731            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16732            // System processes can do UI, and when they do we want to have
16733            // them trim their memory after the user leaves the UI.  To
16734            // facilitate this, here we need to determine whether or not it
16735            // is currently showing UI.
16736            app.systemNoUi = true;
16737            if (app == TOP_APP) {
16738                app.systemNoUi = false;
16739            } else if (activitiesSize > 0) {
16740                for (int j = 0; j < activitiesSize; j++) {
16741                    final ActivityRecord r = app.activities.get(j);
16742                    if (r.visible) {
16743                        app.systemNoUi = false;
16744                    }
16745                }
16746            }
16747            if (!app.systemNoUi) {
16748                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16749            }
16750            return (app.curAdj=app.maxAdj);
16751        }
16752
16753        app.systemNoUi = false;
16754
16755        // Determine the importance of the process, starting with most
16756        // important to least, and assign an appropriate OOM adjustment.
16757        int adj;
16758        int schedGroup;
16759        int procState;
16760        boolean foregroundActivities = false;
16761        BroadcastQueue queue;
16762        if (app == TOP_APP) {
16763            // The last app on the list is the foreground app.
16764            adj = ProcessList.FOREGROUND_APP_ADJ;
16765            schedGroup = Process.THREAD_GROUP_DEFAULT;
16766            app.adjType = "top-activity";
16767            foregroundActivities = true;
16768            procState = ActivityManager.PROCESS_STATE_TOP;
16769        } else if (app.instrumentationClass != null) {
16770            // Don't want to kill running instrumentation.
16771            adj = ProcessList.FOREGROUND_APP_ADJ;
16772            schedGroup = Process.THREAD_GROUP_DEFAULT;
16773            app.adjType = "instrumentation";
16774            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16775        } else if ((queue = isReceivingBroadcast(app)) != null) {
16776            // An app that is currently receiving a broadcast also
16777            // counts as being in the foreground for OOM killer purposes.
16778            // It's placed in a sched group based on the nature of the
16779            // broadcast as reflected by which queue it's active in.
16780            adj = ProcessList.FOREGROUND_APP_ADJ;
16781            schedGroup = (queue == mFgBroadcastQueue)
16782                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16783            app.adjType = "broadcast";
16784            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16785        } else if (app.executingServices.size() > 0) {
16786            // An app that is currently executing a service callback also
16787            // counts as being in the foreground.
16788            adj = ProcessList.FOREGROUND_APP_ADJ;
16789            schedGroup = app.execServicesFg ?
16790                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16791            app.adjType = "exec-service";
16792            procState = ActivityManager.PROCESS_STATE_SERVICE;
16793            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16794        } else {
16795            // As far as we know the process is empty.  We may change our mind later.
16796            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16797            // At this point we don't actually know the adjustment.  Use the cached adj
16798            // value that the caller wants us to.
16799            adj = cachedAdj;
16800            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16801            app.cached = true;
16802            app.empty = true;
16803            app.adjType = "cch-empty";
16804        }
16805
16806        // Examine all activities if not already foreground.
16807        if (!foregroundActivities && activitiesSize > 0) {
16808            for (int j = 0; j < activitiesSize; j++) {
16809                final ActivityRecord r = app.activities.get(j);
16810                if (r.app != app) {
16811                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16812                            + app + "?!?");
16813                    continue;
16814                }
16815                if (r.visible) {
16816                    // App has a visible activity; only upgrade adjustment.
16817                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16818                        adj = ProcessList.VISIBLE_APP_ADJ;
16819                        app.adjType = "visible";
16820                    }
16821                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16822                        procState = ActivityManager.PROCESS_STATE_TOP;
16823                    }
16824                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16825                    app.cached = false;
16826                    app.empty = false;
16827                    foregroundActivities = true;
16828                    break;
16829                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16830                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16831                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16832                        app.adjType = "pausing";
16833                    }
16834                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16835                        procState = ActivityManager.PROCESS_STATE_TOP;
16836                    }
16837                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16838                    app.cached = false;
16839                    app.empty = false;
16840                    foregroundActivities = true;
16841                } else if (r.state == ActivityState.STOPPING) {
16842                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16843                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16844                        app.adjType = "stopping";
16845                    }
16846                    // For the process state, we will at this point consider the
16847                    // process to be cached.  It will be cached either as an activity
16848                    // or empty depending on whether the activity is finishing.  We do
16849                    // this so that we can treat the process as cached for purposes of
16850                    // memory trimming (determing current memory level, trim command to
16851                    // send to process) since there can be an arbitrary number of stopping
16852                    // processes and they should soon all go into the cached state.
16853                    if (!r.finishing) {
16854                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16855                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16856                        }
16857                    }
16858                    app.cached = false;
16859                    app.empty = false;
16860                    foregroundActivities = true;
16861                } else {
16862                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16863                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16864                        app.adjType = "cch-act";
16865                    }
16866                }
16867            }
16868        }
16869
16870        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16871            if (app.foregroundServices) {
16872                // The user is aware of this app, so make it visible.
16873                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16874                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16875                app.cached = false;
16876                app.adjType = "fg-service";
16877                schedGroup = Process.THREAD_GROUP_DEFAULT;
16878            } else if (app.forcingToForeground != null) {
16879                // The user is aware of this app, so make it visible.
16880                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16881                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16882                app.cached = false;
16883                app.adjType = "force-fg";
16884                app.adjSource = app.forcingToForeground;
16885                schedGroup = Process.THREAD_GROUP_DEFAULT;
16886            }
16887        }
16888
16889        if (app == mHeavyWeightProcess) {
16890            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16891                // We don't want to kill the current heavy-weight process.
16892                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16893                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16894                app.cached = false;
16895                app.adjType = "heavy";
16896            }
16897            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16898                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16899            }
16900        }
16901
16902        if (app == mHomeProcess) {
16903            if (adj > ProcessList.HOME_APP_ADJ) {
16904                // This process is hosting what we currently consider to be the
16905                // home app, so we don't want to let it go into the background.
16906                adj = ProcessList.HOME_APP_ADJ;
16907                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16908                app.cached = false;
16909                app.adjType = "home";
16910            }
16911            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16912                procState = ActivityManager.PROCESS_STATE_HOME;
16913            }
16914        }
16915
16916        if (app == mPreviousProcess && app.activities.size() > 0) {
16917            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16918                // This was the previous process that showed UI to the user.
16919                // We want to try to keep it around more aggressively, to give
16920                // a good experience around switching between two apps.
16921                adj = ProcessList.PREVIOUS_APP_ADJ;
16922                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16923                app.cached = false;
16924                app.adjType = "previous";
16925            }
16926            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16927                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16928            }
16929        }
16930
16931        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16932                + " reason=" + app.adjType);
16933
16934        // By default, we use the computed adjustment.  It may be changed if
16935        // there are applications dependent on our services or providers, but
16936        // this gives us a baseline and makes sure we don't get into an
16937        // infinite recursion.
16938        app.adjSeq = mAdjSeq;
16939        app.curRawAdj = adj;
16940        app.hasStartedServices = false;
16941
16942        if (mBackupTarget != null && app == mBackupTarget.app) {
16943            // If possible we want to avoid killing apps while they're being backed up
16944            if (adj > ProcessList.BACKUP_APP_ADJ) {
16945                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
16946                adj = ProcessList.BACKUP_APP_ADJ;
16947                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16948                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16949                }
16950                app.adjType = "backup";
16951                app.cached = false;
16952            }
16953            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16954                procState = ActivityManager.PROCESS_STATE_BACKUP;
16955            }
16956        }
16957
16958        boolean mayBeTop = false;
16959
16960        for (int is = app.services.size()-1;
16961                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16962                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16963                        || procState > ActivityManager.PROCESS_STATE_TOP);
16964                is--) {
16965            ServiceRecord s = app.services.valueAt(is);
16966            if (s.startRequested) {
16967                app.hasStartedServices = true;
16968                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16969                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16970                }
16971                if (app.hasShownUi && app != mHomeProcess) {
16972                    // If this process has shown some UI, let it immediately
16973                    // go to the LRU list because it may be pretty heavy with
16974                    // UI stuff.  We'll tag it with a label just to help
16975                    // debug and understand what is going on.
16976                    if (adj > ProcessList.SERVICE_ADJ) {
16977                        app.adjType = "cch-started-ui-services";
16978                    }
16979                } else {
16980                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16981                        // This service has seen some activity within
16982                        // recent memory, so we will keep its process ahead
16983                        // of the background processes.
16984                        if (adj > ProcessList.SERVICE_ADJ) {
16985                            adj = ProcessList.SERVICE_ADJ;
16986                            app.adjType = "started-services";
16987                            app.cached = false;
16988                        }
16989                    }
16990                    // If we have let the service slide into the background
16991                    // state, still have some text describing what it is doing
16992                    // even though the service no longer has an impact.
16993                    if (adj > ProcessList.SERVICE_ADJ) {
16994                        app.adjType = "cch-started-services";
16995                    }
16996                }
16997            }
16998            for (int conni = s.connections.size()-1;
16999                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17000                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17001                            || procState > ActivityManager.PROCESS_STATE_TOP);
17002                    conni--) {
17003                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17004                for (int i = 0;
17005                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17006                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17007                                || procState > ActivityManager.PROCESS_STATE_TOP);
17008                        i++) {
17009                    // XXX should compute this based on the max of
17010                    // all connected clients.
17011                    ConnectionRecord cr = clist.get(i);
17012                    if (cr.binding.client == app) {
17013                        // Binding to ourself is not interesting.
17014                        continue;
17015                    }
17016                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17017                        ProcessRecord client = cr.binding.client;
17018                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17019                                TOP_APP, doingAll, now);
17020                        int clientProcState = client.curProcState;
17021                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17022                            // If the other app is cached for any reason, for purposes here
17023                            // we are going to consider it empty.  The specific cached state
17024                            // doesn't propagate except under certain conditions.
17025                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17026                        }
17027                        String adjType = null;
17028                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17029                            // Not doing bind OOM management, so treat
17030                            // this guy more like a started service.
17031                            if (app.hasShownUi && app != mHomeProcess) {
17032                                // If this process has shown some UI, let it immediately
17033                                // go to the LRU list because it may be pretty heavy with
17034                                // UI stuff.  We'll tag it with a label just to help
17035                                // debug and understand what is going on.
17036                                if (adj > clientAdj) {
17037                                    adjType = "cch-bound-ui-services";
17038                                }
17039                                app.cached = false;
17040                                clientAdj = adj;
17041                                clientProcState = procState;
17042                            } else {
17043                                if (now >= (s.lastActivity
17044                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17045                                    // This service has not seen activity within
17046                                    // recent memory, so allow it to drop to the
17047                                    // LRU list if there is no other reason to keep
17048                                    // it around.  We'll also tag it with a label just
17049                                    // to help debug and undertand what is going on.
17050                                    if (adj > clientAdj) {
17051                                        adjType = "cch-bound-services";
17052                                    }
17053                                    clientAdj = adj;
17054                                }
17055                            }
17056                        }
17057                        if (adj > clientAdj) {
17058                            // If this process has recently shown UI, and
17059                            // the process that is binding to it is less
17060                            // important than being visible, then we don't
17061                            // care about the binding as much as we care
17062                            // about letting this process get into the LRU
17063                            // list to be killed and restarted if needed for
17064                            // memory.
17065                            if (app.hasShownUi && app != mHomeProcess
17066                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17067                                adjType = "cch-bound-ui-services";
17068                            } else {
17069                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17070                                        |Context.BIND_IMPORTANT)) != 0) {
17071                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17072                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17073                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17074                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17075                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17076                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17077                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17078                                    adj = clientAdj;
17079                                } else {
17080                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17081                                        adj = ProcessList.VISIBLE_APP_ADJ;
17082                                    }
17083                                }
17084                                if (!client.cached) {
17085                                    app.cached = false;
17086                                }
17087                                adjType = "service";
17088                            }
17089                        }
17090                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17091                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17092                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17093                            }
17094                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17095                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17096                                    // Special handling of clients who are in the top state.
17097                                    // We *may* want to consider this process to be in the
17098                                    // top state as well, but only if there is not another
17099                                    // reason for it to be running.  Being on the top is a
17100                                    // special state, meaning you are specifically running
17101                                    // for the current top app.  If the process is already
17102                                    // running in the background for some other reason, it
17103                                    // is more important to continue considering it to be
17104                                    // in the background state.
17105                                    mayBeTop = true;
17106                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17107                                } else {
17108                                    // Special handling for above-top states (persistent
17109                                    // processes).  These should not bring the current process
17110                                    // into the top state, since they are not on top.  Instead
17111                                    // give them the best state after that.
17112                                    clientProcState =
17113                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17114                                }
17115                            }
17116                        } else {
17117                            if (clientProcState <
17118                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17119                                clientProcState =
17120                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17121                            }
17122                        }
17123                        if (procState > clientProcState) {
17124                            procState = clientProcState;
17125                        }
17126                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17127                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17128                            app.pendingUiClean = true;
17129                        }
17130                        if (adjType != null) {
17131                            app.adjType = adjType;
17132                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17133                                    .REASON_SERVICE_IN_USE;
17134                            app.adjSource = cr.binding.client;
17135                            app.adjSourceProcState = clientProcState;
17136                            app.adjTarget = s.name;
17137                        }
17138                    }
17139                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17140                        app.treatLikeActivity = true;
17141                    }
17142                    final ActivityRecord a = cr.activity;
17143                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17144                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17145                                (a.visible || a.state == ActivityState.RESUMED
17146                                 || a.state == ActivityState.PAUSING)) {
17147                            adj = ProcessList.FOREGROUND_APP_ADJ;
17148                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17149                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17150                            }
17151                            app.cached = false;
17152                            app.adjType = "service";
17153                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17154                                    .REASON_SERVICE_IN_USE;
17155                            app.adjSource = a;
17156                            app.adjSourceProcState = procState;
17157                            app.adjTarget = s.name;
17158                        }
17159                    }
17160                }
17161            }
17162        }
17163
17164        for (int provi = app.pubProviders.size()-1;
17165                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17166                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17167                        || procState > ActivityManager.PROCESS_STATE_TOP);
17168                provi--) {
17169            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17170            for (int i = cpr.connections.size()-1;
17171                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17172                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17173                            || procState > ActivityManager.PROCESS_STATE_TOP);
17174                    i--) {
17175                ContentProviderConnection conn = cpr.connections.get(i);
17176                ProcessRecord client = conn.client;
17177                if (client == app) {
17178                    // Being our own client is not interesting.
17179                    continue;
17180                }
17181                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17182                int clientProcState = client.curProcState;
17183                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17184                    // If the other app is cached for any reason, for purposes here
17185                    // we are going to consider it empty.
17186                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17187                }
17188                if (adj > clientAdj) {
17189                    if (app.hasShownUi && app != mHomeProcess
17190                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17191                        app.adjType = "cch-ui-provider";
17192                    } else {
17193                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17194                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17195                        app.adjType = "provider";
17196                    }
17197                    app.cached &= client.cached;
17198                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17199                            .REASON_PROVIDER_IN_USE;
17200                    app.adjSource = client;
17201                    app.adjSourceProcState = clientProcState;
17202                    app.adjTarget = cpr.name;
17203                }
17204                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17205                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17206                        // Special handling of clients who are in the top state.
17207                        // We *may* want to consider this process to be in the
17208                        // top state as well, but only if there is not another
17209                        // reason for it to be running.  Being on the top is a
17210                        // special state, meaning you are specifically running
17211                        // for the current top app.  If the process is already
17212                        // running in the background for some other reason, it
17213                        // is more important to continue considering it to be
17214                        // in the background state.
17215                        mayBeTop = true;
17216                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17217                    } else {
17218                        // Special handling for above-top states (persistent
17219                        // processes).  These should not bring the current process
17220                        // into the top state, since they are not on top.  Instead
17221                        // give them the best state after that.
17222                        clientProcState =
17223                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17224                    }
17225                }
17226                if (procState > clientProcState) {
17227                    procState = clientProcState;
17228                }
17229                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17230                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17231                }
17232            }
17233            // If the provider has external (non-framework) process
17234            // dependencies, ensure that its adjustment is at least
17235            // FOREGROUND_APP_ADJ.
17236            if (cpr.hasExternalProcessHandles()) {
17237                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17238                    adj = ProcessList.FOREGROUND_APP_ADJ;
17239                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17240                    app.cached = false;
17241                    app.adjType = "provider";
17242                    app.adjTarget = cpr.name;
17243                }
17244                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17245                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17246                }
17247            }
17248        }
17249
17250        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17251            // A client of one of our services or providers is in the top state.  We
17252            // *may* want to be in the top state, but not if we are already running in
17253            // the background for some other reason.  For the decision here, we are going
17254            // to pick out a few specific states that we want to remain in when a client
17255            // is top (states that tend to be longer-term) and otherwise allow it to go
17256            // to the top state.
17257            switch (procState) {
17258                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17259                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17260                case ActivityManager.PROCESS_STATE_SERVICE:
17261                    // These all are longer-term states, so pull them up to the top
17262                    // of the background states, but not all the way to the top state.
17263                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17264                    break;
17265                default:
17266                    // Otherwise, top is a better choice, so take it.
17267                    procState = ActivityManager.PROCESS_STATE_TOP;
17268                    break;
17269            }
17270        }
17271
17272        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17273            if (app.hasClientActivities) {
17274                // This is a cached process, but with client activities.  Mark it so.
17275                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17276                app.adjType = "cch-client-act";
17277            } else if (app.treatLikeActivity) {
17278                // This is a cached process, but somebody wants us to treat it like it has
17279                // an activity, okay!
17280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17281                app.adjType = "cch-as-act";
17282            }
17283        }
17284
17285        if (adj == ProcessList.SERVICE_ADJ) {
17286            if (doingAll) {
17287                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17288                mNewNumServiceProcs++;
17289                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17290                if (!app.serviceb) {
17291                    // This service isn't far enough down on the LRU list to
17292                    // normally be a B service, but if we are low on RAM and it
17293                    // is large we want to force it down since we would prefer to
17294                    // keep launcher over it.
17295                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17296                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17297                        app.serviceHighRam = true;
17298                        app.serviceb = true;
17299                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17300                    } else {
17301                        mNewNumAServiceProcs++;
17302                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17303                    }
17304                } else {
17305                    app.serviceHighRam = false;
17306                }
17307            }
17308            if (app.serviceb) {
17309                adj = ProcessList.SERVICE_B_ADJ;
17310            }
17311        }
17312
17313        app.curRawAdj = adj;
17314
17315        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17316        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17317        if (adj > app.maxAdj) {
17318            adj = app.maxAdj;
17319            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17320                schedGroup = Process.THREAD_GROUP_DEFAULT;
17321            }
17322        }
17323
17324        // Do final modification to adj.  Everything we do between here and applying
17325        // the final setAdj must be done in this function, because we will also use
17326        // it when computing the final cached adj later.  Note that we don't need to
17327        // worry about this for max adj above, since max adj will always be used to
17328        // keep it out of the cached vaues.
17329        app.curAdj = app.modifyRawOomAdj(adj);
17330        app.curSchedGroup = schedGroup;
17331        app.curProcState = procState;
17332        app.foregroundActivities = foregroundActivities;
17333
17334        return app.curRawAdj;
17335    }
17336
17337    /**
17338     * Record new PSS sample for a process.
17339     */
17340    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17341        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss*1024, uss*1024);
17342        proc.lastPssTime = now;
17343        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17344        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17345                + ": " + pss + " lastPss=" + proc.lastPss
17346                + " state=" + ProcessList.makeProcStateString(procState));
17347        if (proc.initialIdlePss == 0) {
17348            proc.initialIdlePss = pss;
17349        }
17350        proc.lastPss = pss;
17351        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17352            proc.lastCachedPss = pss;
17353        }
17354
17355        Long check = mMemWatchProcesses.get(proc.processName);
17356        if (check != null) {
17357            if ((pss*1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17358                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17359                if (!isDebuggable) {
17360                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17361                        isDebuggable = true;
17362                    }
17363                }
17364                if (isDebuggable) {
17365                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17366                    final ProcessRecord myProc = proc;
17367                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17368                    mMemWatchDumpProcName = proc.processName;
17369                    mMemWatchDumpFile = heapdumpFile.toString();
17370                    mMemWatchDumpPid = proc.pid;
17371                    mMemWatchDumpUid = proc.uid;
17372                    BackgroundThread.getHandler().post(new Runnable() {
17373                        @Override
17374                        public void run() {
17375                            revokeUriPermission(ActivityThread.currentActivityThread()
17376                                            .getApplicationThread(),
17377                                    DumpHeapActivity.JAVA_URI,
17378                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17379                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17380                                    UserHandle.myUserId());
17381                            ParcelFileDescriptor fd = null;
17382                            try {
17383                                heapdumpFile.delete();
17384                                fd = ParcelFileDescriptor.open(heapdumpFile,
17385                                        ParcelFileDescriptor.MODE_CREATE |
17386                                                ParcelFileDescriptor.MODE_TRUNCATE |
17387                                                ParcelFileDescriptor.MODE_READ_WRITE);
17388                                IApplicationThread thread = myProc.thread;
17389                                if (thread != null) {
17390                                    try {
17391                                        if (DEBUG_PSS) Slog.d(TAG, "Requesting dump heap from "
17392                                                + myProc + " to " + heapdumpFile);
17393                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17394                                    } catch (RemoteException e) {
17395                                    }
17396                                }
17397                            } catch (FileNotFoundException e) {
17398                                e.printStackTrace();
17399                            } finally {
17400                                if (fd != null) {
17401                                    try {
17402                                        fd.close();
17403                                    } catch (IOException e) {
17404                                    }
17405                                }
17406                            }
17407                        }
17408                    });
17409                } else {
17410                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
17411                            + ", but debugging not enabled");
17412                }
17413            }
17414        }
17415    }
17416
17417    /**
17418     * Schedule PSS collection of a process.
17419     */
17420    void requestPssLocked(ProcessRecord proc, int procState) {
17421        if (mPendingPssProcesses.contains(proc)) {
17422            return;
17423        }
17424        if (mPendingPssProcesses.size() == 0) {
17425            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17426        }
17427        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17428        proc.pssProcState = procState;
17429        mPendingPssProcesses.add(proc);
17430    }
17431
17432    /**
17433     * Schedule PSS collection of all processes.
17434     */
17435    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17436        if (!always) {
17437            if (now < (mLastFullPssTime +
17438                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17439                return;
17440            }
17441        }
17442        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17443        mLastFullPssTime = now;
17444        mFullPssPending = true;
17445        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17446        mPendingPssProcesses.clear();
17447        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17448            ProcessRecord app = mLruProcesses.get(i);
17449            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17450                app.pssProcState = app.setProcState;
17451                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17452                        mTestPssMode, isSleeping(), now);
17453                mPendingPssProcesses.add(app);
17454            }
17455        }
17456        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17457    }
17458
17459    public void setTestPssMode(boolean enabled) {
17460        synchronized (this) {
17461            mTestPssMode = enabled;
17462            if (enabled) {
17463                // Whenever we enable the mode, we want to take a snapshot all of current
17464                // process mem use.
17465                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17466            }
17467        }
17468    }
17469
17470    /**
17471     * Ask a given process to GC right now.
17472     */
17473    final void performAppGcLocked(ProcessRecord app) {
17474        try {
17475            app.lastRequestedGc = SystemClock.uptimeMillis();
17476            if (app.thread != null) {
17477                if (app.reportLowMemory) {
17478                    app.reportLowMemory = false;
17479                    app.thread.scheduleLowMemory();
17480                } else {
17481                    app.thread.processInBackground();
17482                }
17483            }
17484        } catch (Exception e) {
17485            // whatever.
17486        }
17487    }
17488
17489    /**
17490     * Returns true if things are idle enough to perform GCs.
17491     */
17492    private final boolean canGcNowLocked() {
17493        boolean processingBroadcasts = false;
17494        for (BroadcastQueue q : mBroadcastQueues) {
17495            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17496                processingBroadcasts = true;
17497            }
17498        }
17499        return !processingBroadcasts
17500                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17501    }
17502
17503    /**
17504     * Perform GCs on all processes that are waiting for it, but only
17505     * if things are idle.
17506     */
17507    final void performAppGcsLocked() {
17508        final int N = mProcessesToGc.size();
17509        if (N <= 0) {
17510            return;
17511        }
17512        if (canGcNowLocked()) {
17513            while (mProcessesToGc.size() > 0) {
17514                ProcessRecord proc = mProcessesToGc.remove(0);
17515                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17516                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17517                            <= SystemClock.uptimeMillis()) {
17518                        // To avoid spamming the system, we will GC processes one
17519                        // at a time, waiting a few seconds between each.
17520                        performAppGcLocked(proc);
17521                        scheduleAppGcsLocked();
17522                        return;
17523                    } else {
17524                        // It hasn't been long enough since we last GCed this
17525                        // process...  put it in the list to wait for its time.
17526                        addProcessToGcListLocked(proc);
17527                        break;
17528                    }
17529                }
17530            }
17531
17532            scheduleAppGcsLocked();
17533        }
17534    }
17535
17536    /**
17537     * If all looks good, perform GCs on all processes waiting for them.
17538     */
17539    final void performAppGcsIfAppropriateLocked() {
17540        if (canGcNowLocked()) {
17541            performAppGcsLocked();
17542            return;
17543        }
17544        // Still not idle, wait some more.
17545        scheduleAppGcsLocked();
17546    }
17547
17548    /**
17549     * Schedule the execution of all pending app GCs.
17550     */
17551    final void scheduleAppGcsLocked() {
17552        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17553
17554        if (mProcessesToGc.size() > 0) {
17555            // Schedule a GC for the time to the next process.
17556            ProcessRecord proc = mProcessesToGc.get(0);
17557            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17558
17559            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17560            long now = SystemClock.uptimeMillis();
17561            if (when < (now+GC_TIMEOUT)) {
17562                when = now + GC_TIMEOUT;
17563            }
17564            mHandler.sendMessageAtTime(msg, when);
17565        }
17566    }
17567
17568    /**
17569     * Add a process to the array of processes waiting to be GCed.  Keeps the
17570     * list in sorted order by the last GC time.  The process can't already be
17571     * on the list.
17572     */
17573    final void addProcessToGcListLocked(ProcessRecord proc) {
17574        boolean added = false;
17575        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17576            if (mProcessesToGc.get(i).lastRequestedGc <
17577                    proc.lastRequestedGc) {
17578                added = true;
17579                mProcessesToGc.add(i+1, proc);
17580                break;
17581            }
17582        }
17583        if (!added) {
17584            mProcessesToGc.add(0, proc);
17585        }
17586    }
17587
17588    /**
17589     * Set up to ask a process to GC itself.  This will either do it
17590     * immediately, or put it on the list of processes to gc the next
17591     * time things are idle.
17592     */
17593    final void scheduleAppGcLocked(ProcessRecord app) {
17594        long now = SystemClock.uptimeMillis();
17595        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17596            return;
17597        }
17598        if (!mProcessesToGc.contains(app)) {
17599            addProcessToGcListLocked(app);
17600            scheduleAppGcsLocked();
17601        }
17602    }
17603
17604    final void checkExcessivePowerUsageLocked(boolean doKills) {
17605        updateCpuStatsNow();
17606
17607        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17608        boolean doWakeKills = doKills;
17609        boolean doCpuKills = doKills;
17610        if (mLastPowerCheckRealtime == 0) {
17611            doWakeKills = false;
17612        }
17613        if (mLastPowerCheckUptime == 0) {
17614            doCpuKills = false;
17615        }
17616        if (stats.isScreenOn()) {
17617            doWakeKills = false;
17618        }
17619        final long curRealtime = SystemClock.elapsedRealtime();
17620        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17621        final long curUptime = SystemClock.uptimeMillis();
17622        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17623        mLastPowerCheckRealtime = curRealtime;
17624        mLastPowerCheckUptime = curUptime;
17625        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17626            doWakeKills = false;
17627        }
17628        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17629            doCpuKills = false;
17630        }
17631        int i = mLruProcesses.size();
17632        while (i > 0) {
17633            i--;
17634            ProcessRecord app = mLruProcesses.get(i);
17635            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17636                long wtime;
17637                synchronized (stats) {
17638                    wtime = stats.getProcessWakeTime(app.info.uid,
17639                            app.pid, curRealtime);
17640                }
17641                long wtimeUsed = wtime - app.lastWakeTime;
17642                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17643                if (DEBUG_POWER) {
17644                    StringBuilder sb = new StringBuilder(128);
17645                    sb.append("Wake for ");
17646                    app.toShortString(sb);
17647                    sb.append(": over ");
17648                    TimeUtils.formatDuration(realtimeSince, sb);
17649                    sb.append(" used ");
17650                    TimeUtils.formatDuration(wtimeUsed, sb);
17651                    sb.append(" (");
17652                    sb.append((wtimeUsed*100)/realtimeSince);
17653                    sb.append("%)");
17654                    Slog.i(TAG, sb.toString());
17655                    sb.setLength(0);
17656                    sb.append("CPU for ");
17657                    app.toShortString(sb);
17658                    sb.append(": over ");
17659                    TimeUtils.formatDuration(uptimeSince, sb);
17660                    sb.append(" used ");
17661                    TimeUtils.formatDuration(cputimeUsed, sb);
17662                    sb.append(" (");
17663                    sb.append((cputimeUsed*100)/uptimeSince);
17664                    sb.append("%)");
17665                    Slog.i(TAG, sb.toString());
17666                }
17667                // If a process has held a wake lock for more
17668                // than 50% of the time during this period,
17669                // that sounds bad.  Kill!
17670                if (doWakeKills && realtimeSince > 0
17671                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17672                    synchronized (stats) {
17673                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17674                                realtimeSince, wtimeUsed);
17675                    }
17676                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17677                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17678                } else if (doCpuKills && uptimeSince > 0
17679                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17680                    synchronized (stats) {
17681                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17682                                uptimeSince, cputimeUsed);
17683                    }
17684                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17685                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17686                } else {
17687                    app.lastWakeTime = wtime;
17688                    app.lastCpuTime = app.curCpuTime;
17689                }
17690            }
17691        }
17692    }
17693
17694    private final boolean applyOomAdjLocked(ProcessRecord app,
17695            ProcessRecord TOP_APP, boolean doingAll, long now) {
17696        boolean success = true;
17697
17698        if (app.curRawAdj != app.setRawAdj) {
17699            app.setRawAdj = app.curRawAdj;
17700        }
17701
17702        int changes = 0;
17703
17704        if (app.curAdj != app.setAdj) {
17705            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17706            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17707                TAG, "Set " + app.pid + " " + app.processName +
17708                " adj " + app.curAdj + ": " + app.adjType);
17709            app.setAdj = app.curAdj;
17710        }
17711
17712        if (app.setSchedGroup != app.curSchedGroup) {
17713            app.setSchedGroup = app.curSchedGroup;
17714            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17715                    "Setting process group of " + app.processName
17716                    + " to " + app.curSchedGroup);
17717            if (app.waitingToKill != null &&
17718                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17719                app.kill(app.waitingToKill, true);
17720                success = false;
17721            } else {
17722                if (true) {
17723                    long oldId = Binder.clearCallingIdentity();
17724                    try {
17725                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17726                    } catch (Exception e) {
17727                        Slog.w(TAG, "Failed setting process group of " + app.pid
17728                                + " to " + app.curSchedGroup);
17729                        e.printStackTrace();
17730                    } finally {
17731                        Binder.restoreCallingIdentity(oldId);
17732                    }
17733                } else {
17734                    if (app.thread != null) {
17735                        try {
17736                            app.thread.setSchedulingGroup(app.curSchedGroup);
17737                        } catch (RemoteException e) {
17738                        }
17739                    }
17740                }
17741                Process.setSwappiness(app.pid,
17742                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17743            }
17744        }
17745        if (app.repForegroundActivities != app.foregroundActivities) {
17746            app.repForegroundActivities = app.foregroundActivities;
17747            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17748        }
17749        if (app.repProcState != app.curProcState) {
17750            app.repProcState = app.curProcState;
17751            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17752            if (app.thread != null) {
17753                try {
17754                    if (false) {
17755                        //RuntimeException h = new RuntimeException("here");
17756                        Slog.i(TAG, "Sending new process state " + app.repProcState
17757                                + " to " + app /*, h*/);
17758                    }
17759                    app.thread.setProcessState(app.repProcState);
17760                } catch (RemoteException e) {
17761                }
17762            }
17763        }
17764        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17765                app.setProcState)) {
17766            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17767                // Experimental code to more aggressively collect pss while
17768                // running test...  the problem is that this tends to collect
17769                // the data right when a process is transitioning between process
17770                // states, which well tend to give noisy data.
17771                long start = SystemClock.uptimeMillis();
17772                long pss = Debug.getPss(app.pid, mTmpLong, null);
17773                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
17774                mPendingPssProcesses.remove(app);
17775                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17776                        + " to " + app.curProcState + ": "
17777                        + (SystemClock.uptimeMillis()-start) + "ms");
17778            }
17779            app.lastStateTime = now;
17780            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17781                    mTestPssMode, isSleeping(), now);
17782            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17783                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17784                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17785                    + (app.nextPssTime-now) + ": " + app);
17786        } else {
17787            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17788                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17789                    mTestPssMode)))) {
17790                requestPssLocked(app, app.setProcState);
17791                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17792                        mTestPssMode, isSleeping(), now);
17793            } else if (false && DEBUG_PSS) {
17794                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17795            }
17796        }
17797        if (app.setProcState != app.curProcState) {
17798            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17799                    "Proc state change of " + app.processName
17800                    + " to " + app.curProcState);
17801            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17802            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17803            if (setImportant && !curImportant) {
17804                // This app is no longer something we consider important enough to allow to
17805                // use arbitrary amounts of battery power.  Note
17806                // its current wake lock time to later know to kill it if
17807                // it is not behaving well.
17808                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17809                synchronized (stats) {
17810                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17811                            app.pid, SystemClock.elapsedRealtime());
17812                }
17813                app.lastCpuTime = app.curCpuTime;
17814
17815            }
17816            app.setProcState = app.curProcState;
17817            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17818                app.notCachedSinceIdle = false;
17819            }
17820            if (!doingAll) {
17821                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17822            } else {
17823                app.procStateChanged = true;
17824            }
17825        }
17826
17827        if (changes != 0) {
17828            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17829            int i = mPendingProcessChanges.size()-1;
17830            ProcessChangeItem item = null;
17831            while (i >= 0) {
17832                item = mPendingProcessChanges.get(i);
17833                if (item.pid == app.pid) {
17834                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17835                    break;
17836                }
17837                i--;
17838            }
17839            if (i < 0) {
17840                // No existing item in pending changes; need a new one.
17841                final int NA = mAvailProcessChanges.size();
17842                if (NA > 0) {
17843                    item = mAvailProcessChanges.remove(NA-1);
17844                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17845                } else {
17846                    item = new ProcessChangeItem();
17847                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17848                }
17849                item.changes = 0;
17850                item.pid = app.pid;
17851                item.uid = app.info.uid;
17852                if (mPendingProcessChanges.size() == 0) {
17853                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17854                            "*** Enqueueing dispatch processes changed!");
17855                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17856                }
17857                mPendingProcessChanges.add(item);
17858            }
17859            item.changes |= changes;
17860            item.processState = app.repProcState;
17861            item.foregroundActivities = app.repForegroundActivities;
17862            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17863                    + Integer.toHexString(System.identityHashCode(item))
17864                    + " " + app.toShortString() + ": changes=" + item.changes
17865                    + " procState=" + item.processState
17866                    + " foreground=" + item.foregroundActivities
17867                    + " type=" + app.adjType + " source=" + app.adjSource
17868                    + " target=" + app.adjTarget);
17869        }
17870
17871        return success;
17872    }
17873
17874    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17875        if (proc.thread != null) {
17876            if (proc.baseProcessTracker != null) {
17877                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17878            }
17879            if (proc.repProcState >= 0) {
17880                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17881                        proc.repProcState);
17882            }
17883        }
17884    }
17885
17886    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17887            ProcessRecord TOP_APP, boolean doingAll, long now) {
17888        if (app.thread == null) {
17889            return false;
17890        }
17891
17892        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17893
17894        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17895    }
17896
17897    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17898            boolean oomAdj) {
17899        if (isForeground != proc.foregroundServices) {
17900            proc.foregroundServices = isForeground;
17901            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17902                    proc.info.uid);
17903            if (isForeground) {
17904                if (curProcs == null) {
17905                    curProcs = new ArrayList<ProcessRecord>();
17906                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17907                }
17908                if (!curProcs.contains(proc)) {
17909                    curProcs.add(proc);
17910                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17911                            proc.info.packageName, proc.info.uid);
17912                }
17913            } else {
17914                if (curProcs != null) {
17915                    if (curProcs.remove(proc)) {
17916                        mBatteryStatsService.noteEvent(
17917                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17918                                proc.info.packageName, proc.info.uid);
17919                        if (curProcs.size() <= 0) {
17920                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17921                        }
17922                    }
17923                }
17924            }
17925            if (oomAdj) {
17926                updateOomAdjLocked();
17927            }
17928        }
17929    }
17930
17931    private final ActivityRecord resumedAppLocked() {
17932        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17933        String pkg;
17934        int uid;
17935        if (act != null) {
17936            pkg = act.packageName;
17937            uid = act.info.applicationInfo.uid;
17938        } else {
17939            pkg = null;
17940            uid = -1;
17941        }
17942        // Has the UID or resumed package name changed?
17943        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17944                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17945            if (mCurResumedPackage != null) {
17946                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17947                        mCurResumedPackage, mCurResumedUid);
17948            }
17949            mCurResumedPackage = pkg;
17950            mCurResumedUid = uid;
17951            if (mCurResumedPackage != null) {
17952                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17953                        mCurResumedPackage, mCurResumedUid);
17954            }
17955        }
17956        return act;
17957    }
17958
17959    final boolean updateOomAdjLocked(ProcessRecord app) {
17960        final ActivityRecord TOP_ACT = resumedAppLocked();
17961        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17962        final boolean wasCached = app.cached;
17963
17964        mAdjSeq++;
17965
17966        // This is the desired cached adjusment we want to tell it to use.
17967        // If our app is currently cached, we know it, and that is it.  Otherwise,
17968        // we don't know it yet, and it needs to now be cached we will then
17969        // need to do a complete oom adj.
17970        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17971                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17972        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17973                SystemClock.uptimeMillis());
17974        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17975            // Changed to/from cached state, so apps after it in the LRU
17976            // list may also be changed.
17977            updateOomAdjLocked();
17978        }
17979        return success;
17980    }
17981
17982    final void updateOomAdjLocked() {
17983        final ActivityRecord TOP_ACT = resumedAppLocked();
17984        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17985        final long now = SystemClock.uptimeMillis();
17986        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17987        final int N = mLruProcesses.size();
17988
17989        if (false) {
17990            RuntimeException e = new RuntimeException();
17991            e.fillInStackTrace();
17992            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17993        }
17994
17995        mAdjSeq++;
17996        mNewNumServiceProcs = 0;
17997        mNewNumAServiceProcs = 0;
17998
17999        final int emptyProcessLimit;
18000        final int cachedProcessLimit;
18001        if (mProcessLimit <= 0) {
18002            emptyProcessLimit = cachedProcessLimit = 0;
18003        } else if (mProcessLimit == 1) {
18004            emptyProcessLimit = 1;
18005            cachedProcessLimit = 0;
18006        } else {
18007            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18008            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18009        }
18010
18011        // Let's determine how many processes we have running vs.
18012        // how many slots we have for background processes; we may want
18013        // to put multiple processes in a slot of there are enough of
18014        // them.
18015        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18016                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18017        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18018        if (numEmptyProcs > cachedProcessLimit) {
18019            // If there are more empty processes than our limit on cached
18020            // processes, then use the cached process limit for the factor.
18021            // This ensures that the really old empty processes get pushed
18022            // down to the bottom, so if we are running low on memory we will
18023            // have a better chance at keeping around more cached processes
18024            // instead of a gazillion empty processes.
18025            numEmptyProcs = cachedProcessLimit;
18026        }
18027        int emptyFactor = numEmptyProcs/numSlots;
18028        if (emptyFactor < 1) emptyFactor = 1;
18029        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18030        if (cachedFactor < 1) cachedFactor = 1;
18031        int stepCached = 0;
18032        int stepEmpty = 0;
18033        int numCached = 0;
18034        int numEmpty = 0;
18035        int numTrimming = 0;
18036
18037        mNumNonCachedProcs = 0;
18038        mNumCachedHiddenProcs = 0;
18039
18040        // First update the OOM adjustment for each of the
18041        // application processes based on their current state.
18042        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18043        int nextCachedAdj = curCachedAdj+1;
18044        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18045        int nextEmptyAdj = curEmptyAdj+2;
18046        for (int i=N-1; i>=0; i--) {
18047            ProcessRecord app = mLruProcesses.get(i);
18048            if (!app.killedByAm && app.thread != null) {
18049                app.procStateChanged = false;
18050                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18051
18052                // If we haven't yet assigned the final cached adj
18053                // to the process, do that now.
18054                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18055                    switch (app.curProcState) {
18056                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18057                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18058                            // This process is a cached process holding activities...
18059                            // assign it the next cached value for that type, and then
18060                            // step that cached level.
18061                            app.curRawAdj = curCachedAdj;
18062                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18063                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18064                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18065                                    + ")");
18066                            if (curCachedAdj != nextCachedAdj) {
18067                                stepCached++;
18068                                if (stepCached >= cachedFactor) {
18069                                    stepCached = 0;
18070                                    curCachedAdj = nextCachedAdj;
18071                                    nextCachedAdj += 2;
18072                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18073                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18074                                    }
18075                                }
18076                            }
18077                            break;
18078                        default:
18079                            // For everything else, assign next empty cached process
18080                            // level and bump that up.  Note that this means that
18081                            // long-running services that have dropped down to the
18082                            // cached level will be treated as empty (since their process
18083                            // state is still as a service), which is what we want.
18084                            app.curRawAdj = curEmptyAdj;
18085                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18086                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18087                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18088                                    + ")");
18089                            if (curEmptyAdj != nextEmptyAdj) {
18090                                stepEmpty++;
18091                                if (stepEmpty >= emptyFactor) {
18092                                    stepEmpty = 0;
18093                                    curEmptyAdj = nextEmptyAdj;
18094                                    nextEmptyAdj += 2;
18095                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18096                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18097                                    }
18098                                }
18099                            }
18100                            break;
18101                    }
18102                }
18103
18104                applyOomAdjLocked(app, TOP_APP, true, now);
18105
18106                // Count the number of process types.
18107                switch (app.curProcState) {
18108                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18109                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18110                        mNumCachedHiddenProcs++;
18111                        numCached++;
18112                        if (numCached > cachedProcessLimit) {
18113                            app.kill("cached #" + numCached, true);
18114                        }
18115                        break;
18116                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18117                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18118                                && app.lastActivityTime < oldTime) {
18119                            app.kill("empty for "
18120                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18121                                    / 1000) + "s", true);
18122                        } else {
18123                            numEmpty++;
18124                            if (numEmpty > emptyProcessLimit) {
18125                                app.kill("empty #" + numEmpty, true);
18126                            }
18127                        }
18128                        break;
18129                    default:
18130                        mNumNonCachedProcs++;
18131                        break;
18132                }
18133
18134                if (app.isolated && app.services.size() <= 0) {
18135                    // If this is an isolated process, and there are no
18136                    // services running in it, then the process is no longer
18137                    // needed.  We agressively kill these because we can by
18138                    // definition not re-use the same process again, and it is
18139                    // good to avoid having whatever code was running in them
18140                    // left sitting around after no longer needed.
18141                    app.kill("isolated not needed", true);
18142                }
18143
18144                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18145                        && !app.killedByAm) {
18146                    numTrimming++;
18147                }
18148            }
18149        }
18150
18151        mNumServiceProcs = mNewNumServiceProcs;
18152
18153        // Now determine the memory trimming level of background processes.
18154        // Unfortunately we need to start at the back of the list to do this
18155        // properly.  We only do this if the number of background apps we
18156        // are managing to keep around is less than half the maximum we desire;
18157        // if we are keeping a good number around, we'll let them use whatever
18158        // memory they want.
18159        final int numCachedAndEmpty = numCached + numEmpty;
18160        int memFactor;
18161        if (numCached <= ProcessList.TRIM_CACHED_APPS
18162                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18163            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18164                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18165            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18166                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18167            } else {
18168                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18169            }
18170        } else {
18171            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18172        }
18173        // We always allow the memory level to go up (better).  We only allow it to go
18174        // down if we are in a state where that is allowed, *and* the total number of processes
18175        // has gone down since last time.
18176        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18177                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18178                + " last=" + mLastNumProcesses);
18179        if (memFactor > mLastMemoryLevel) {
18180            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18181                memFactor = mLastMemoryLevel;
18182                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18183            }
18184        }
18185        mLastMemoryLevel = memFactor;
18186        mLastNumProcesses = mLruProcesses.size();
18187        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18188        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18189        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18190            if (mLowRamStartTime == 0) {
18191                mLowRamStartTime = now;
18192            }
18193            int step = 0;
18194            int fgTrimLevel;
18195            switch (memFactor) {
18196                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18197                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18198                    break;
18199                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18200                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18201                    break;
18202                default:
18203                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18204                    break;
18205            }
18206            int factor = numTrimming/3;
18207            int minFactor = 2;
18208            if (mHomeProcess != null) minFactor++;
18209            if (mPreviousProcess != null) minFactor++;
18210            if (factor < minFactor) factor = minFactor;
18211            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18212            for (int i=N-1; i>=0; i--) {
18213                ProcessRecord app = mLruProcesses.get(i);
18214                if (allChanged || app.procStateChanged) {
18215                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18216                    app.procStateChanged = false;
18217                }
18218                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18219                        && !app.killedByAm) {
18220                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18221                        try {
18222                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18223                                    "Trimming memory of " + app.processName
18224                                    + " to " + curLevel);
18225                            app.thread.scheduleTrimMemory(curLevel);
18226                        } catch (RemoteException e) {
18227                        }
18228                        if (false) {
18229                            // For now we won't do this; our memory trimming seems
18230                            // to be good enough at this point that destroying
18231                            // activities causes more harm than good.
18232                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18233                                    && app != mHomeProcess && app != mPreviousProcess) {
18234                                // Need to do this on its own message because the stack may not
18235                                // be in a consistent state at this point.
18236                                // For these apps we will also finish their activities
18237                                // to help them free memory.
18238                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18239                            }
18240                        }
18241                    }
18242                    app.trimMemoryLevel = curLevel;
18243                    step++;
18244                    if (step >= factor) {
18245                        step = 0;
18246                        switch (curLevel) {
18247                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18248                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18249                                break;
18250                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18251                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18252                                break;
18253                        }
18254                    }
18255                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18256                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18257                            && app.thread != null) {
18258                        try {
18259                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18260                                    "Trimming memory of heavy-weight " + app.processName
18261                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18262                            app.thread.scheduleTrimMemory(
18263                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18264                        } catch (RemoteException e) {
18265                        }
18266                    }
18267                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18268                } else {
18269                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18270                            || app.systemNoUi) && app.pendingUiClean) {
18271                        // If this application is now in the background and it
18272                        // had done UI, then give it the special trim level to
18273                        // have it free UI resources.
18274                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18275                        if (app.trimMemoryLevel < level && app.thread != null) {
18276                            try {
18277                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18278                                        "Trimming memory of bg-ui " + app.processName
18279                                        + " to " + level);
18280                                app.thread.scheduleTrimMemory(level);
18281                            } catch (RemoteException e) {
18282                            }
18283                        }
18284                        app.pendingUiClean = false;
18285                    }
18286                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18287                        try {
18288                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18289                                    "Trimming memory of fg " + app.processName
18290                                    + " to " + fgTrimLevel);
18291                            app.thread.scheduleTrimMemory(fgTrimLevel);
18292                        } catch (RemoteException e) {
18293                        }
18294                    }
18295                    app.trimMemoryLevel = fgTrimLevel;
18296                }
18297            }
18298        } else {
18299            if (mLowRamStartTime != 0) {
18300                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18301                mLowRamStartTime = 0;
18302            }
18303            for (int i=N-1; i>=0; i--) {
18304                ProcessRecord app = mLruProcesses.get(i);
18305                if (allChanged || app.procStateChanged) {
18306                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18307                    app.procStateChanged = false;
18308                }
18309                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18310                        || app.systemNoUi) && app.pendingUiClean) {
18311                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18312                            && app.thread != null) {
18313                        try {
18314                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18315                                    "Trimming memory of ui hidden " + app.processName
18316                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18317                            app.thread.scheduleTrimMemory(
18318                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18319                        } catch (RemoteException e) {
18320                        }
18321                    }
18322                    app.pendingUiClean = false;
18323                }
18324                app.trimMemoryLevel = 0;
18325            }
18326        }
18327
18328        if (mAlwaysFinishActivities) {
18329            // Need to do this on its own message because the stack may not
18330            // be in a consistent state at this point.
18331            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18332        }
18333
18334        if (allChanged) {
18335            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18336        }
18337
18338        if (mProcessStats.shouldWriteNowLocked(now)) {
18339            mHandler.post(new Runnable() {
18340                @Override public void run() {
18341                    synchronized (ActivityManagerService.this) {
18342                        mProcessStats.writeStateAsyncLocked();
18343                    }
18344                }
18345            });
18346        }
18347
18348        if (DEBUG_OOM_ADJ) {
18349            if (false) {
18350                RuntimeException here = new RuntimeException("here");
18351                here.fillInStackTrace();
18352                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18353            } else {
18354                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18355            }
18356        }
18357    }
18358
18359    final void trimApplications() {
18360        synchronized (this) {
18361            int i;
18362
18363            // First remove any unused application processes whose package
18364            // has been removed.
18365            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18366                final ProcessRecord app = mRemovedProcesses.get(i);
18367                if (app.activities.size() == 0
18368                        && app.curReceiver == null && app.services.size() == 0) {
18369                    Slog.i(
18370                        TAG, "Exiting empty application process "
18371                        + app.processName + " ("
18372                        + (app.thread != null ? app.thread.asBinder() : null)
18373                        + ")\n");
18374                    if (app.pid > 0 && app.pid != MY_PID) {
18375                        app.kill("empty", false);
18376                    } else {
18377                        try {
18378                            app.thread.scheduleExit();
18379                        } catch (Exception e) {
18380                            // Ignore exceptions.
18381                        }
18382                    }
18383                    cleanUpApplicationRecordLocked(app, false, true, -1);
18384                    mRemovedProcesses.remove(i);
18385
18386                    if (app.persistent) {
18387                        addAppLocked(app.info, false, null /* ABI override */);
18388                    }
18389                }
18390            }
18391
18392            // Now update the oom adj for all processes.
18393            updateOomAdjLocked();
18394        }
18395    }
18396
18397    /** This method sends the specified signal to each of the persistent apps */
18398    public void signalPersistentProcesses(int sig) throws RemoteException {
18399        if (sig != Process.SIGNAL_USR1) {
18400            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18401        }
18402
18403        synchronized (this) {
18404            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18405                    != PackageManager.PERMISSION_GRANTED) {
18406                throw new SecurityException("Requires permission "
18407                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18408            }
18409
18410            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18411                ProcessRecord r = mLruProcesses.get(i);
18412                if (r.thread != null && r.persistent) {
18413                    Process.sendSignal(r.pid, sig);
18414                }
18415            }
18416        }
18417    }
18418
18419    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18420        if (proc == null || proc == mProfileProc) {
18421            proc = mProfileProc;
18422            profileType = mProfileType;
18423            clearProfilerLocked();
18424        }
18425        if (proc == null) {
18426            return;
18427        }
18428        try {
18429            proc.thread.profilerControl(false, null, profileType);
18430        } catch (RemoteException e) {
18431            throw new IllegalStateException("Process disappeared");
18432        }
18433    }
18434
18435    private void clearProfilerLocked() {
18436        if (mProfileFd != null) {
18437            try {
18438                mProfileFd.close();
18439            } catch (IOException e) {
18440            }
18441        }
18442        mProfileApp = null;
18443        mProfileProc = null;
18444        mProfileFile = null;
18445        mProfileType = 0;
18446        mAutoStopProfiler = false;
18447        mSamplingInterval = 0;
18448    }
18449
18450    public boolean profileControl(String process, int userId, boolean start,
18451            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18452
18453        try {
18454            synchronized (this) {
18455                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18456                // its own permission.
18457                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18458                        != PackageManager.PERMISSION_GRANTED) {
18459                    throw new SecurityException("Requires permission "
18460                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18461                }
18462
18463                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18464                    throw new IllegalArgumentException("null profile info or fd");
18465                }
18466
18467                ProcessRecord proc = null;
18468                if (process != null) {
18469                    proc = findProcessLocked(process, userId, "profileControl");
18470                }
18471
18472                if (start && (proc == null || proc.thread == null)) {
18473                    throw new IllegalArgumentException("Unknown process: " + process);
18474                }
18475
18476                if (start) {
18477                    stopProfilerLocked(null, 0);
18478                    setProfileApp(proc.info, proc.processName, profilerInfo);
18479                    mProfileProc = proc;
18480                    mProfileType = profileType;
18481                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18482                    try {
18483                        fd = fd.dup();
18484                    } catch (IOException e) {
18485                        fd = null;
18486                    }
18487                    profilerInfo.profileFd = fd;
18488                    proc.thread.profilerControl(start, profilerInfo, profileType);
18489                    fd = null;
18490                    mProfileFd = null;
18491                } else {
18492                    stopProfilerLocked(proc, profileType);
18493                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18494                        try {
18495                            profilerInfo.profileFd.close();
18496                        } catch (IOException e) {
18497                        }
18498                    }
18499                }
18500
18501                return true;
18502            }
18503        } catch (RemoteException e) {
18504            throw new IllegalStateException("Process disappeared");
18505        } finally {
18506            if (profilerInfo != null && profilerInfo.profileFd != null) {
18507                try {
18508                    profilerInfo.profileFd.close();
18509                } catch (IOException e) {
18510                }
18511            }
18512        }
18513    }
18514
18515    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18516        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18517                userId, true, ALLOW_FULL_ONLY, callName, null);
18518        ProcessRecord proc = null;
18519        try {
18520            int pid = Integer.parseInt(process);
18521            synchronized (mPidsSelfLocked) {
18522                proc = mPidsSelfLocked.get(pid);
18523            }
18524        } catch (NumberFormatException e) {
18525        }
18526
18527        if (proc == null) {
18528            ArrayMap<String, SparseArray<ProcessRecord>> all
18529                    = mProcessNames.getMap();
18530            SparseArray<ProcessRecord> procs = all.get(process);
18531            if (procs != null && procs.size() > 0) {
18532                proc = procs.valueAt(0);
18533                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18534                    for (int i=1; i<procs.size(); i++) {
18535                        ProcessRecord thisProc = procs.valueAt(i);
18536                        if (thisProc.userId == userId) {
18537                            proc = thisProc;
18538                            break;
18539                        }
18540                    }
18541                }
18542            }
18543        }
18544
18545        return proc;
18546    }
18547
18548    public boolean dumpHeap(String process, int userId, boolean managed,
18549            String path, ParcelFileDescriptor fd) throws RemoteException {
18550
18551        try {
18552            synchronized (this) {
18553                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18554                // its own permission (same as profileControl).
18555                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18556                        != PackageManager.PERMISSION_GRANTED) {
18557                    throw new SecurityException("Requires permission "
18558                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18559                }
18560
18561                if (fd == null) {
18562                    throw new IllegalArgumentException("null fd");
18563                }
18564
18565                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18566                if (proc == null || proc.thread == null) {
18567                    throw new IllegalArgumentException("Unknown process: " + process);
18568                }
18569
18570                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18571                if (!isDebuggable) {
18572                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18573                        throw new SecurityException("Process not debuggable: " + proc);
18574                    }
18575                }
18576
18577                proc.thread.dumpHeap(managed, path, fd);
18578                fd = null;
18579                return true;
18580            }
18581        } catch (RemoteException e) {
18582            throw new IllegalStateException("Process disappeared");
18583        } finally {
18584            if (fd != null) {
18585                try {
18586                    fd.close();
18587                } catch (IOException e) {
18588                }
18589            }
18590        }
18591    }
18592
18593    @Override
18594    public void setDumpHeapDebugLimit(String processName, long maxMemSize) {
18595        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
18596                "setDumpHeapDebugLimit()");
18597        synchronized (this) {
18598            if (maxMemSize > 0) {
18599                mMemWatchProcesses.put(processName, maxMemSize);
18600                mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18601            } else {
18602                mMemWatchProcesses.remove(processName);
18603            }
18604        }
18605    }
18606
18607    @Override
18608    public void dumpHeapFinished(String path) {
18609        synchronized (this) {
18610            if (Binder.getCallingPid() != mMemWatchDumpPid) {
18611                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
18612                        + " does not match last pid " + mMemWatchDumpPid);
18613                return;
18614            }
18615            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
18616                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
18617                        + " does not match last path " + mMemWatchDumpFile);
18618                return;
18619            }
18620            if (DEBUG_PSS) Slog.d(TAG, "Dump heap finished for " + path);
18621            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18622        }
18623    }
18624
18625    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18626    public void monitor() {
18627        synchronized (this) { }
18628    }
18629
18630    void onCoreSettingsChange(Bundle settings) {
18631        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18632            ProcessRecord processRecord = mLruProcesses.get(i);
18633            try {
18634                if (processRecord.thread != null) {
18635                    processRecord.thread.setCoreSettings(settings);
18636                }
18637            } catch (RemoteException re) {
18638                /* ignore */
18639            }
18640        }
18641    }
18642
18643    // Multi-user methods
18644
18645    /**
18646     * Start user, if its not already running, but don't bring it to foreground.
18647     */
18648    @Override
18649    public boolean startUserInBackground(final int userId) {
18650        return startUser(userId, /* foreground */ false);
18651    }
18652
18653    /**
18654     * Start user, if its not already running, and bring it to foreground.
18655     */
18656    boolean startUserInForeground(final int userId, Dialog dlg) {
18657        boolean result = startUser(userId, /* foreground */ true);
18658        dlg.dismiss();
18659        return result;
18660    }
18661
18662    /**
18663     * Refreshes the list of users related to the current user when either a
18664     * user switch happens or when a new related user is started in the
18665     * background.
18666     */
18667    private void updateCurrentProfileIdsLocked() {
18668        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18669                mCurrentUserId, false /* enabledOnly */);
18670        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18671        for (int i = 0; i < currentProfileIds.length; i++) {
18672            currentProfileIds[i] = profiles.get(i).id;
18673        }
18674        mCurrentProfileIds = currentProfileIds;
18675
18676        synchronized (mUserProfileGroupIdsSelfLocked) {
18677            mUserProfileGroupIdsSelfLocked.clear();
18678            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18679            for (int i = 0; i < users.size(); i++) {
18680                UserInfo user = users.get(i);
18681                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18682                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18683                }
18684            }
18685        }
18686    }
18687
18688    private Set<Integer> getProfileIdsLocked(int userId) {
18689        Set<Integer> userIds = new HashSet<Integer>();
18690        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18691                userId, false /* enabledOnly */);
18692        for (UserInfo user : profiles) {
18693            userIds.add(Integer.valueOf(user.id));
18694        }
18695        return userIds;
18696    }
18697
18698    @Override
18699    public boolean switchUser(final int userId) {
18700        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18701        String userName;
18702        synchronized (this) {
18703            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18704            if (userInfo == null) {
18705                Slog.w(TAG, "No user info for user #" + userId);
18706                return false;
18707            }
18708            if (userInfo.isManagedProfile()) {
18709                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18710                return false;
18711            }
18712            userName = userInfo.name;
18713            mTargetUserId = userId;
18714        }
18715        mHandler.removeMessages(START_USER_SWITCH_MSG);
18716        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18717        return true;
18718    }
18719
18720    private void showUserSwitchDialog(int userId, String userName) {
18721        // The dialog will show and then initiate the user switch by calling startUserInForeground
18722        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18723                true /* above system */);
18724        d.show();
18725    }
18726
18727    private boolean startUser(final int userId, final boolean foreground) {
18728        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18729                != PackageManager.PERMISSION_GRANTED) {
18730            String msg = "Permission Denial: switchUser() from pid="
18731                    + Binder.getCallingPid()
18732                    + ", uid=" + Binder.getCallingUid()
18733                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18734            Slog.w(TAG, msg);
18735            throw new SecurityException(msg);
18736        }
18737
18738        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18739
18740        final long ident = Binder.clearCallingIdentity();
18741        try {
18742            synchronized (this) {
18743                final int oldUserId = mCurrentUserId;
18744                if (oldUserId == userId) {
18745                    return true;
18746                }
18747
18748                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
18749                        "startUser");
18750
18751                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18752                if (userInfo == null) {
18753                    Slog.w(TAG, "No user info for user #" + userId);
18754                    return false;
18755                }
18756                if (foreground && userInfo.isManagedProfile()) {
18757                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18758                    return false;
18759                }
18760
18761                if (foreground) {
18762                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18763                            R.anim.screen_user_enter);
18764                }
18765
18766                boolean needStart = false;
18767
18768                // If the user we are switching to is not currently started, then
18769                // we need to start it now.
18770                if (mStartedUsers.get(userId) == null) {
18771                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18772                    updateStartedUserArrayLocked();
18773                    needStart = true;
18774                }
18775
18776                final Integer userIdInt = Integer.valueOf(userId);
18777                mUserLru.remove(userIdInt);
18778                mUserLru.add(userIdInt);
18779
18780                if (foreground) {
18781                    mCurrentUserId = userId;
18782                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18783                    updateCurrentProfileIdsLocked();
18784                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18785                    // Once the internal notion of the active user has switched, we lock the device
18786                    // with the option to show the user switcher on the keyguard.
18787                    mWindowManager.lockNow(null);
18788                } else {
18789                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18790                    updateCurrentProfileIdsLocked();
18791                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18792                    mUserLru.remove(currentUserIdInt);
18793                    mUserLru.add(currentUserIdInt);
18794                }
18795
18796                final UserStartedState uss = mStartedUsers.get(userId);
18797
18798                // Make sure user is in the started state.  If it is currently
18799                // stopping, we need to knock that off.
18800                if (uss.mState == UserStartedState.STATE_STOPPING) {
18801                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18802                    // so we can just fairly silently bring the user back from
18803                    // the almost-dead.
18804                    uss.mState = UserStartedState.STATE_RUNNING;
18805                    updateStartedUserArrayLocked();
18806                    needStart = true;
18807                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18808                    // This means ACTION_SHUTDOWN has been sent, so we will
18809                    // need to treat this as a new boot of the user.
18810                    uss.mState = UserStartedState.STATE_BOOTING;
18811                    updateStartedUserArrayLocked();
18812                    needStart = true;
18813                }
18814
18815                if (uss.mState == UserStartedState.STATE_BOOTING) {
18816                    // Booting up a new user, need to tell system services about it.
18817                    // Note that this is on the same handler as scheduling of broadcasts,
18818                    // which is important because it needs to go first.
18819                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18820                }
18821
18822                if (foreground) {
18823                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18824                            oldUserId));
18825                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18826                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18827                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18828                            oldUserId, userId, uss));
18829                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18830                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18831                }
18832
18833                if (needStart) {
18834                    // Send USER_STARTED broadcast
18835                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18836                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18837                            | Intent.FLAG_RECEIVER_FOREGROUND);
18838                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18839                    broadcastIntentLocked(null, null, intent,
18840                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18841                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18842                }
18843
18844                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18845                    if (userId != UserHandle.USER_OWNER) {
18846                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18847                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18848                        broadcastIntentLocked(null, null, intent, null,
18849                                new IIntentReceiver.Stub() {
18850                                    public void performReceive(Intent intent, int resultCode,
18851                                            String data, Bundle extras, boolean ordered,
18852                                            boolean sticky, int sendingUser) {
18853                                        onUserInitialized(uss, foreground, oldUserId, userId);
18854                                    }
18855                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18856                                true, false, MY_PID, Process.SYSTEM_UID,
18857                                userId);
18858                        uss.initializing = true;
18859                    } else {
18860                        getUserManagerLocked().makeInitialized(userInfo.id);
18861                    }
18862                }
18863
18864                if (foreground) {
18865                    if (!uss.initializing) {
18866                        moveUserToForeground(uss, oldUserId, userId);
18867                    }
18868                } else {
18869                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18870                }
18871
18872                if (needStart) {
18873                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18874                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18875                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18876                    broadcastIntentLocked(null, null, intent,
18877                            null, new IIntentReceiver.Stub() {
18878                                @Override
18879                                public void performReceive(Intent intent, int resultCode, String data,
18880                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18881                                        throws RemoteException {
18882                                }
18883                            }, 0, null, null,
18884                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18885                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18886                }
18887            }
18888        } finally {
18889            Binder.restoreCallingIdentity(ident);
18890        }
18891
18892        return true;
18893    }
18894
18895    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18896        long ident = Binder.clearCallingIdentity();
18897        try {
18898            Intent intent;
18899            if (oldUserId >= 0) {
18900                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18901                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18902                int count = profiles.size();
18903                for (int i = 0; i < count; i++) {
18904                    int profileUserId = profiles.get(i).id;
18905                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18906                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18907                            | Intent.FLAG_RECEIVER_FOREGROUND);
18908                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18909                    broadcastIntentLocked(null, null, intent,
18910                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18911                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18912                }
18913            }
18914            if (newUserId >= 0) {
18915                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18916                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18917                int count = profiles.size();
18918                for (int i = 0; i < count; i++) {
18919                    int profileUserId = profiles.get(i).id;
18920                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18921                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18922                            | Intent.FLAG_RECEIVER_FOREGROUND);
18923                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18924                    broadcastIntentLocked(null, null, intent,
18925                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18926                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18927                }
18928                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18929                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18930                        | Intent.FLAG_RECEIVER_FOREGROUND);
18931                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18932                broadcastIntentLocked(null, null, intent,
18933                        null, null, 0, null, null,
18934                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18935                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18936            }
18937        } finally {
18938            Binder.restoreCallingIdentity(ident);
18939        }
18940    }
18941
18942    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18943            final int newUserId) {
18944        final int N = mUserSwitchObservers.beginBroadcast();
18945        if (N > 0) {
18946            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18947                int mCount = 0;
18948                @Override
18949                public void sendResult(Bundle data) throws RemoteException {
18950                    synchronized (ActivityManagerService.this) {
18951                        if (mCurUserSwitchCallback == this) {
18952                            mCount++;
18953                            if (mCount == N) {
18954                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18955                            }
18956                        }
18957                    }
18958                }
18959            };
18960            synchronized (this) {
18961                uss.switching = true;
18962                mCurUserSwitchCallback = callback;
18963            }
18964            for (int i=0; i<N; i++) {
18965                try {
18966                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18967                            newUserId, callback);
18968                } catch (RemoteException e) {
18969                }
18970            }
18971        } else {
18972            synchronized (this) {
18973                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18974            }
18975        }
18976        mUserSwitchObservers.finishBroadcast();
18977    }
18978
18979    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18980        synchronized (this) {
18981            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18982            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18983        }
18984    }
18985
18986    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18987        mCurUserSwitchCallback = null;
18988        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18989        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18990                oldUserId, newUserId, uss));
18991    }
18992
18993    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18994        synchronized (this) {
18995            if (foreground) {
18996                moveUserToForeground(uss, oldUserId, newUserId);
18997            }
18998        }
18999
19000        completeSwitchAndInitalize(uss, newUserId, true, false);
19001    }
19002
19003    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19004        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19005        if (homeInFront) {
19006            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19007        } else {
19008            mStackSupervisor.resumeTopActivitiesLocked();
19009        }
19010        EventLogTags.writeAmSwitchUser(newUserId);
19011        getUserManagerLocked().userForeground(newUserId);
19012        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19013    }
19014
19015    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19016        completeSwitchAndInitalize(uss, newUserId, false, true);
19017    }
19018
19019    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19020            boolean clearInitializing, boolean clearSwitching) {
19021        boolean unfrozen = false;
19022        synchronized (this) {
19023            if (clearInitializing) {
19024                uss.initializing = false;
19025                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19026            }
19027            if (clearSwitching) {
19028                uss.switching = false;
19029            }
19030            if (!uss.switching && !uss.initializing) {
19031                mWindowManager.stopFreezingScreen();
19032                unfrozen = true;
19033            }
19034        }
19035        if (unfrozen) {
19036            final int N = mUserSwitchObservers.beginBroadcast();
19037            for (int i=0; i<N; i++) {
19038                try {
19039                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19040                } catch (RemoteException e) {
19041                }
19042            }
19043            mUserSwitchObservers.finishBroadcast();
19044        }
19045        stopGuestUserIfBackground();
19046    }
19047
19048    /**
19049     * Stops the guest user if it has gone to the background.
19050     */
19051    private void stopGuestUserIfBackground() {
19052        synchronized (this) {
19053            final int num = mUserLru.size();
19054            for (int i = 0; i < num; i++) {
19055                Integer oldUserId = mUserLru.get(i);
19056                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19057                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19058                        || oldUss.mState == UserStartedState.STATE_STOPPING
19059                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19060                    continue;
19061                }
19062                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19063                if (userInfo.isGuest()) {
19064                    // This is a user to be stopped.
19065                    stopUserLocked(oldUserId, null);
19066                    break;
19067                }
19068            }
19069        }
19070    }
19071
19072    void scheduleStartProfilesLocked() {
19073        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19074            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19075                    DateUtils.SECOND_IN_MILLIS);
19076        }
19077    }
19078
19079    void startProfilesLocked() {
19080        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19081        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19082                mCurrentUserId, false /* enabledOnly */);
19083        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19084        for (UserInfo user : profiles) {
19085            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19086                    && user.id != mCurrentUserId) {
19087                toStart.add(user);
19088            }
19089        }
19090        final int n = toStart.size();
19091        int i = 0;
19092        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19093            startUserInBackground(toStart.get(i).id);
19094        }
19095        if (i < n) {
19096            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19097        }
19098    }
19099
19100    void finishUserBoot(UserStartedState uss) {
19101        synchronized (this) {
19102            if (uss.mState == UserStartedState.STATE_BOOTING
19103                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19104                uss.mState = UserStartedState.STATE_RUNNING;
19105                final int userId = uss.mHandle.getIdentifier();
19106                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19107                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19108                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19109                broadcastIntentLocked(null, null, intent,
19110                        null, null, 0, null, null,
19111                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19112                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19113            }
19114        }
19115    }
19116
19117    void finishUserSwitch(UserStartedState uss) {
19118        synchronized (this) {
19119            finishUserBoot(uss);
19120
19121            startProfilesLocked();
19122
19123            int num = mUserLru.size();
19124            int i = 0;
19125            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19126                Integer oldUserId = mUserLru.get(i);
19127                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19128                if (oldUss == null) {
19129                    // Shouldn't happen, but be sane if it does.
19130                    mUserLru.remove(i);
19131                    num--;
19132                    continue;
19133                }
19134                if (oldUss.mState == UserStartedState.STATE_STOPPING
19135                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19136                    // This user is already stopping, doesn't count.
19137                    num--;
19138                    i++;
19139                    continue;
19140                }
19141                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19142                    // Owner and current can't be stopped, but count as running.
19143                    i++;
19144                    continue;
19145                }
19146                // This is a user to be stopped.
19147                stopUserLocked(oldUserId, null);
19148                num--;
19149                i++;
19150            }
19151        }
19152    }
19153
19154    @Override
19155    public int stopUser(final int userId, final IStopUserCallback callback) {
19156        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19157                != PackageManager.PERMISSION_GRANTED) {
19158            String msg = "Permission Denial: switchUser() from pid="
19159                    + Binder.getCallingPid()
19160                    + ", uid=" + Binder.getCallingUid()
19161                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19162            Slog.w(TAG, msg);
19163            throw new SecurityException(msg);
19164        }
19165        if (userId <= 0) {
19166            throw new IllegalArgumentException("Can't stop primary user " + userId);
19167        }
19168        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19169        synchronized (this) {
19170            return stopUserLocked(userId, callback);
19171        }
19172    }
19173
19174    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19175        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19176        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19177            return ActivityManager.USER_OP_IS_CURRENT;
19178        }
19179
19180        final UserStartedState uss = mStartedUsers.get(userId);
19181        if (uss == null) {
19182            // User is not started, nothing to do...  but we do need to
19183            // callback if requested.
19184            if (callback != null) {
19185                mHandler.post(new Runnable() {
19186                    @Override
19187                    public void run() {
19188                        try {
19189                            callback.userStopped(userId);
19190                        } catch (RemoteException e) {
19191                        }
19192                    }
19193                });
19194            }
19195            return ActivityManager.USER_OP_SUCCESS;
19196        }
19197
19198        if (callback != null) {
19199            uss.mStopCallbacks.add(callback);
19200        }
19201
19202        if (uss.mState != UserStartedState.STATE_STOPPING
19203                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19204            uss.mState = UserStartedState.STATE_STOPPING;
19205            updateStartedUserArrayLocked();
19206
19207            long ident = Binder.clearCallingIdentity();
19208            try {
19209                // We are going to broadcast ACTION_USER_STOPPING and then
19210                // once that is done send a final ACTION_SHUTDOWN and then
19211                // stop the user.
19212                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19213                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19214                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19215                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19216                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19217                // This is the result receiver for the final shutdown broadcast.
19218                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19219                    @Override
19220                    public void performReceive(Intent intent, int resultCode, String data,
19221                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19222                        finishUserStop(uss);
19223                    }
19224                };
19225                // This is the result receiver for the initial stopping broadcast.
19226                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19227                    @Override
19228                    public void performReceive(Intent intent, int resultCode, String data,
19229                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19230                        // On to the next.
19231                        synchronized (ActivityManagerService.this) {
19232                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19233                                // Whoops, we are being started back up.  Abort, abort!
19234                                return;
19235                            }
19236                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19237                        }
19238                        mBatteryStatsService.noteEvent(
19239                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19240                                Integer.toString(userId), userId);
19241                        mSystemServiceManager.stopUser(userId);
19242                        broadcastIntentLocked(null, null, shutdownIntent,
19243                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19244                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19245                    }
19246                };
19247                // Kick things off.
19248                broadcastIntentLocked(null, null, stoppingIntent,
19249                        null, stoppingReceiver, 0, null, null,
19250                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19251                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19252            } finally {
19253                Binder.restoreCallingIdentity(ident);
19254            }
19255        }
19256
19257        return ActivityManager.USER_OP_SUCCESS;
19258    }
19259
19260    void finishUserStop(UserStartedState uss) {
19261        final int userId = uss.mHandle.getIdentifier();
19262        boolean stopped;
19263        ArrayList<IStopUserCallback> callbacks;
19264        synchronized (this) {
19265            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19266            if (mStartedUsers.get(userId) != uss) {
19267                stopped = false;
19268            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19269                stopped = false;
19270            } else {
19271                stopped = true;
19272                // User can no longer run.
19273                mStartedUsers.remove(userId);
19274                mUserLru.remove(Integer.valueOf(userId));
19275                updateStartedUserArrayLocked();
19276
19277                // Clean up all state and processes associated with the user.
19278                // Kill all the processes for the user.
19279                forceStopUserLocked(userId, "finish user");
19280            }
19281
19282            // Explicitly remove the old information in mRecentTasks.
19283            mRecentTasks.removeTasksForUserLocked(userId);
19284        }
19285
19286        for (int i=0; i<callbacks.size(); i++) {
19287            try {
19288                if (stopped) callbacks.get(i).userStopped(userId);
19289                else callbacks.get(i).userStopAborted(userId);
19290            } catch (RemoteException e) {
19291            }
19292        }
19293
19294        if (stopped) {
19295            mSystemServiceManager.cleanupUser(userId);
19296            synchronized (this) {
19297                mStackSupervisor.removeUserLocked(userId);
19298            }
19299        }
19300    }
19301
19302    @Override
19303    public UserInfo getCurrentUser() {
19304        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19305                != PackageManager.PERMISSION_GRANTED) && (
19306                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19307                != PackageManager.PERMISSION_GRANTED)) {
19308            String msg = "Permission Denial: getCurrentUser() from pid="
19309                    + Binder.getCallingPid()
19310                    + ", uid=" + Binder.getCallingUid()
19311                    + " requires " + INTERACT_ACROSS_USERS;
19312            Slog.w(TAG, msg);
19313            throw new SecurityException(msg);
19314        }
19315        synchronized (this) {
19316            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19317            return getUserManagerLocked().getUserInfo(userId);
19318        }
19319    }
19320
19321    int getCurrentUserIdLocked() {
19322        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19323    }
19324
19325    @Override
19326    public boolean isUserRunning(int userId, boolean orStopped) {
19327        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19328                != PackageManager.PERMISSION_GRANTED) {
19329            String msg = "Permission Denial: isUserRunning() from pid="
19330                    + Binder.getCallingPid()
19331                    + ", uid=" + Binder.getCallingUid()
19332                    + " requires " + INTERACT_ACROSS_USERS;
19333            Slog.w(TAG, msg);
19334            throw new SecurityException(msg);
19335        }
19336        synchronized (this) {
19337            return isUserRunningLocked(userId, orStopped);
19338        }
19339    }
19340
19341    boolean isUserRunningLocked(int userId, boolean orStopped) {
19342        UserStartedState state = mStartedUsers.get(userId);
19343        if (state == null) {
19344            return false;
19345        }
19346        if (orStopped) {
19347            return true;
19348        }
19349        return state.mState != UserStartedState.STATE_STOPPING
19350                && state.mState != UserStartedState.STATE_SHUTDOWN;
19351    }
19352
19353    @Override
19354    public int[] getRunningUserIds() {
19355        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19356                != PackageManager.PERMISSION_GRANTED) {
19357            String msg = "Permission Denial: isUserRunning() from pid="
19358                    + Binder.getCallingPid()
19359                    + ", uid=" + Binder.getCallingUid()
19360                    + " requires " + INTERACT_ACROSS_USERS;
19361            Slog.w(TAG, msg);
19362            throw new SecurityException(msg);
19363        }
19364        synchronized (this) {
19365            return mStartedUserArray;
19366        }
19367    }
19368
19369    private void updateStartedUserArrayLocked() {
19370        int num = 0;
19371        for (int i=0; i<mStartedUsers.size();  i++) {
19372            UserStartedState uss = mStartedUsers.valueAt(i);
19373            // This list does not include stopping users.
19374            if (uss.mState != UserStartedState.STATE_STOPPING
19375                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19376                num++;
19377            }
19378        }
19379        mStartedUserArray = new int[num];
19380        num = 0;
19381        for (int i=0; i<mStartedUsers.size();  i++) {
19382            UserStartedState uss = mStartedUsers.valueAt(i);
19383            if (uss.mState != UserStartedState.STATE_STOPPING
19384                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19385                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19386                num++;
19387            }
19388        }
19389    }
19390
19391    @Override
19392    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19393        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19394                != PackageManager.PERMISSION_GRANTED) {
19395            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19396                    + Binder.getCallingPid()
19397                    + ", uid=" + Binder.getCallingUid()
19398                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19399            Slog.w(TAG, msg);
19400            throw new SecurityException(msg);
19401        }
19402
19403        mUserSwitchObservers.register(observer);
19404    }
19405
19406    @Override
19407    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19408        mUserSwitchObservers.unregister(observer);
19409    }
19410
19411    private boolean userExists(int userId) {
19412        if (userId == 0) {
19413            return true;
19414        }
19415        UserManagerService ums = getUserManagerLocked();
19416        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19417    }
19418
19419    int[] getUsersLocked() {
19420        UserManagerService ums = getUserManagerLocked();
19421        return ums != null ? ums.getUserIds() : new int[] { 0 };
19422    }
19423
19424    UserManagerService getUserManagerLocked() {
19425        if (mUserManager == null) {
19426            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19427            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19428        }
19429        return mUserManager;
19430    }
19431
19432    private int applyUserId(int uid, int userId) {
19433        return UserHandle.getUid(userId, uid);
19434    }
19435
19436    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19437        if (info == null) return null;
19438        ApplicationInfo newInfo = new ApplicationInfo(info);
19439        newInfo.uid = applyUserId(info.uid, userId);
19440        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19441                + info.packageName;
19442        return newInfo;
19443    }
19444
19445    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19446        if (aInfo == null
19447                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19448            return aInfo;
19449        }
19450
19451        ActivityInfo info = new ActivityInfo(aInfo);
19452        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19453        return info;
19454    }
19455
19456    private final class LocalService extends ActivityManagerInternal {
19457        @Override
19458        public void onWakefulnessChanged(int wakefulness) {
19459            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19460        }
19461
19462        @Override
19463        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19464                String processName, String abiOverride, int uid, Runnable crashHandler) {
19465            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19466                    processName, abiOverride, uid, crashHandler);
19467        }
19468    }
19469
19470    /**
19471     * An implementation of IAppTask, that allows an app to manage its own tasks via
19472     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19473     * only the process that calls getAppTasks() can call the AppTask methods.
19474     */
19475    class AppTaskImpl extends IAppTask.Stub {
19476        private int mTaskId;
19477        private int mCallingUid;
19478
19479        public AppTaskImpl(int taskId, int callingUid) {
19480            mTaskId = taskId;
19481            mCallingUid = callingUid;
19482        }
19483
19484        private void checkCaller() {
19485            if (mCallingUid != Binder.getCallingUid()) {
19486                throw new SecurityException("Caller " + mCallingUid
19487                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19488            }
19489        }
19490
19491        @Override
19492        public void finishAndRemoveTask() {
19493            checkCaller();
19494
19495            synchronized (ActivityManagerService.this) {
19496                long origId = Binder.clearCallingIdentity();
19497                try {
19498                    if (!removeTaskByIdLocked(mTaskId, false)) {
19499                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19500                    }
19501                } finally {
19502                    Binder.restoreCallingIdentity(origId);
19503                }
19504            }
19505        }
19506
19507        @Override
19508        public ActivityManager.RecentTaskInfo getTaskInfo() {
19509            checkCaller();
19510
19511            synchronized (ActivityManagerService.this) {
19512                long origId = Binder.clearCallingIdentity();
19513                try {
19514                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19515                    if (tr == null) {
19516                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19517                    }
19518                    return createRecentTaskInfoFromTaskRecord(tr);
19519                } finally {
19520                    Binder.restoreCallingIdentity(origId);
19521                }
19522            }
19523        }
19524
19525        @Override
19526        public void moveToFront() {
19527            checkCaller();
19528            // Will bring task to front if it already has a root activity.
19529            startActivityFromRecentsInner(mTaskId, null);
19530        }
19531
19532        @Override
19533        public int startActivity(IBinder whoThread, String callingPackage,
19534                Intent intent, String resolvedType, Bundle options) {
19535            checkCaller();
19536
19537            int callingUser = UserHandle.getCallingUserId();
19538            TaskRecord tr;
19539            IApplicationThread appThread;
19540            synchronized (ActivityManagerService.this) {
19541                tr = mRecentTasks.taskForIdLocked(mTaskId);
19542                if (tr == null) {
19543                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19544                }
19545                appThread = ApplicationThreadNative.asInterface(whoThread);
19546                if (appThread == null) {
19547                    throw new IllegalArgumentException("Bad app thread " + appThread);
19548                }
19549            }
19550            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19551                    resolvedType, null, null, null, null, 0, 0, null, null,
19552                    null, options, callingUser, null, tr);
19553        }
19554
19555        @Override
19556        public void setExcludeFromRecents(boolean exclude) {
19557            checkCaller();
19558
19559            synchronized (ActivityManagerService.this) {
19560                long origId = Binder.clearCallingIdentity();
19561                try {
19562                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19563                    if (tr == null) {
19564                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19565                    }
19566                    Intent intent = tr.getBaseIntent();
19567                    if (exclude) {
19568                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19569                    } else {
19570                        intent.setFlags(intent.getFlags()
19571                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19572                    }
19573                } finally {
19574                    Binder.restoreCallingIdentity(origId);
19575                }
19576            }
19577        }
19578    }
19579}
19580