ActivityManagerService.java revision 9987b6e867d862c27cd1339d7fa8135b75d565f1
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import android.view.Display;
61import com.android.internal.R;
62import com.android.internal.annotations.GuardedBy;
63import com.android.internal.app.IAppOpsService;
64import com.android.internal.app.IVoiceInteractor;
65import com.android.internal.app.ProcessMap;
66import com.android.internal.app.ProcessStats;
67import com.android.internal.os.BackgroundThread;
68import com.android.internal.os.BatteryStatsImpl;
69import com.android.internal.os.ProcessCpuTracker;
70import com.android.internal.os.TransferPipe;
71import com.android.internal.os.Zygote;
72import com.android.internal.util.FastPrintWriter;
73import com.android.internal.util.FastXmlSerializer;
74import com.android.internal.util.MemInfoReader;
75import com.android.internal.util.Preconditions;
76import com.android.server.AppOpsService;
77import com.android.server.AttributeCache;
78import com.android.server.IntentResolver;
79import com.android.server.LocalServices;
80import com.android.server.ServiceThread;
81import com.android.server.SystemService;
82import com.android.server.SystemServiceManager;
83import com.android.server.Watchdog;
84import com.android.server.am.ActivityStack.ActivityState;
85import com.android.server.firewall.IntentFirewall;
86import com.android.server.pm.Installer;
87import com.android.server.pm.UserManagerService;
88import com.android.server.statusbar.StatusBarManagerInternal;
89import com.android.server.wm.AppTransition;
90import com.android.server.wm.WindowManagerService;
91import com.google.android.collect.Lists;
92import com.google.android.collect.Maps;
93
94import libcore.io.IoUtils;
95
96import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlPullParserException;
98import org.xmlpull.v1.XmlSerializer;
99
100import android.app.Activity;
101import android.app.ActivityManager;
102import android.app.ActivityManager.RunningTaskInfo;
103import android.app.ActivityManager.StackInfo;
104import android.app.ActivityManagerInternal;
105import android.app.ActivityManagerNative;
106import android.app.ActivityOptions;
107import android.app.ActivityThread;
108import android.app.AlertDialog;
109import android.app.AppGlobals;
110import android.app.ApplicationErrorReport;
111import android.app.Dialog;
112import android.app.IActivityController;
113import android.app.IApplicationThread;
114import android.app.IInstrumentationWatcher;
115import android.app.INotificationManager;
116import android.app.IProcessObserver;
117import android.app.IServiceConnection;
118import android.app.IStopUserCallback;
119import android.app.IUiAutomationConnection;
120import android.app.IUserSwitchObserver;
121import android.app.Instrumentation;
122import android.app.Notification;
123import android.app.NotificationManager;
124import android.app.PendingIntent;
125import android.app.backup.IBackupManager;
126import android.content.ActivityNotFoundException;
127import android.content.BroadcastReceiver;
128import android.content.ClipData;
129import android.content.ComponentCallbacks2;
130import android.content.ComponentName;
131import android.content.ContentProvider;
132import android.content.ContentResolver;
133import android.content.Context;
134import android.content.DialogInterface;
135import android.content.IContentProvider;
136import android.content.IIntentReceiver;
137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.IntentFilter;
140import android.content.IntentSender;
141import android.content.pm.ActivityInfo;
142import android.content.pm.ApplicationInfo;
143import android.content.pm.ConfigurationInfo;
144import android.content.pm.IPackageDataObserver;
145import android.content.pm.IPackageManager;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageManager;
149import android.content.pm.ParceledListSlice;
150import android.content.pm.UserInfo;
151import android.content.pm.PackageManager.NameNotFoundException;
152import android.content.pm.PathPermission;
153import android.content.pm.ProviderInfo;
154import android.content.pm.ResolveInfo;
155import android.content.pm.ServiceInfo;
156import android.content.res.CompatibilityInfo;
157import android.content.res.Configuration;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.DropBoxManager;
166import android.os.Environment;
167import android.os.FactoryTest;
168import android.os.FileObserver;
169import android.os.FileUtils;
170import android.os.Handler;
171import android.os.IBinder;
172import android.os.IPermissionController;
173import android.os.IProcessInfoService;
174import android.os.IRemoteCallback;
175import android.os.IUserManager;
176import android.os.Looper;
177import android.os.Message;
178import android.os.Parcel;
179import android.os.ParcelFileDescriptor;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.SELinux;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.provider.Settings;
193import android.text.format.DateUtils;
194import android.text.format.Time;
195import android.util.AtomicFile;
196import android.util.EventLog;
197import android.util.Log;
198import android.util.Pair;
199import android.util.PrintWriterPrinter;
200import android.util.Slog;
201import android.util.SparseArray;
202import android.util.TimeUtils;
203import android.util.Xml;
204import android.view.Gravity;
205import android.view.LayoutInflater;
206import android.view.View;
207import android.view.WindowManager;
208
209import dalvik.system.VMRuntime;
210
211import java.io.BufferedInputStream;
212import java.io.BufferedOutputStream;
213import java.io.DataInputStream;
214import java.io.DataOutputStream;
215import java.io.File;
216import java.io.FileDescriptor;
217import java.io.FileInputStream;
218import java.io.FileNotFoundException;
219import java.io.FileOutputStream;
220import java.io.IOException;
221import java.io.InputStreamReader;
222import java.io.PrintWriter;
223import java.io.StringWriter;
224import java.lang.ref.WeakReference;
225import java.util.ArrayList;
226import java.util.Arrays;
227import java.util.Collections;
228import java.util.Comparator;
229import java.util.HashMap;
230import java.util.HashSet;
231import java.util.Iterator;
232import java.util.List;
233import java.util.Locale;
234import java.util.Map;
235import java.util.Set;
236import java.util.concurrent.atomic.AtomicBoolean;
237import java.util.concurrent.atomic.AtomicLong;
238
239public final class ActivityManagerService extends ActivityManagerNative
240        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
241
242    private static final String USER_DATA_DIR = "/data/user/";
243    // File that stores last updated system version and called preboot receivers
244    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
245
246    static final String TAG = "ActivityManager";
247    static final String TAG_MU = "ActivityManagerServiceMU";
248    static final boolean DEBUG = false;
249    static final boolean localLOGV = DEBUG;
250    static final boolean DEBUG_BACKUP = localLOGV || false;
251    static final boolean DEBUG_BROADCAST = localLOGV || false;
252    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
253    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
254    static final boolean DEBUG_CLEANUP = localLOGV || false;
255    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
256    static final boolean DEBUG_FOCUS = false;
257    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
258    static final boolean DEBUG_MU = localLOGV || false;
259    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
260    static final boolean DEBUG_LRU = localLOGV || false;
261    static final boolean DEBUG_PAUSE = localLOGV || false;
262    static final boolean DEBUG_POWER = localLOGV || false;
263    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
264    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
265    static final boolean DEBUG_PROCESSES = localLOGV || false;
266    static final boolean DEBUG_PROVIDER = localLOGV || false;
267    static final boolean DEBUG_RESULTS = localLOGV || false;
268    static final boolean DEBUG_SERVICE = localLOGV || false;
269    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
270    static final boolean DEBUG_STACK = localLOGV || false;
271    static final boolean DEBUG_SWITCH = localLOGV || false;
272    static final boolean DEBUG_TASKS = localLOGV || false;
273    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
274    static final boolean DEBUG_TRANSITION = localLOGV || false;
275    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
276    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
277    static final boolean DEBUG_VISBILITY = localLOGV || false;
278    static final boolean DEBUG_PSS = localLOGV || false;
279    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
280    static final boolean DEBUG_RECENTS = localLOGV || false;
281    static final boolean VALIDATE_TOKENS = false;
282    static final boolean SHOW_ACTIVITY_START_TIME = true;
283
284    // Control over CPU and battery monitoring.
285    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
286    static final boolean MONITOR_CPU_USAGE = true;
287    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
288    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
289    static final boolean MONITOR_THREAD_CPU_USAGE = false;
290
291    // The flags that are set for all calls we make to the package manager.
292    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
293
294    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
295
296    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
297
298    // Maximum number recent bitmaps to keep in memory.
299    static final int MAX_RECENT_BITMAPS = 3;
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_BACKGROUND_BROADCAST) {
408            Slog.i(TAG, "Broadcast intent " + intent + " on "
409                    + (isFg ? "foreground" : "background")
410                    + " queue");
411        }
412        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
413    }
414
415    /**
416     * Activity we have told the window manager to have key focus.
417     */
418    ActivityRecord mFocusedActivity = null;
419
420    /**
421     * List of intents that were used to start the most recent tasks.
422     */
423    ArrayList<TaskRecord> mRecentTasks;
424    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
425
426    /**
427     * For addAppTask: cached of the last activity component that was added.
428     */
429    ComponentName mLastAddedTaskComponent;
430
431    /**
432     * For addAppTask: cached of the last activity uid that was added.
433     */
434    int mLastAddedTaskUid;
435
436    /**
437     * For addAppTask: cached of the last ActivityInfo that was added.
438     */
439    ActivityInfo mLastAddedTaskActivity;
440
441    public class PendingAssistExtras extends Binder implements Runnable {
442        public final ActivityRecord activity;
443        public final Bundle extras;
444        public final Intent intent;
445        public final String hint;
446        public final int userHandle;
447        public boolean haveResult = false;
448        public Bundle result = null;
449        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
450                String _hint, int _userHandle) {
451            activity = _activity;
452            extras = _extras;
453            intent = _intent;
454            hint = _hint;
455            userHandle = _userHandle;
456        }
457        @Override
458        public void run() {
459            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
460            synchronized (this) {
461                haveResult = true;
462                notifyAll();
463            }
464        }
465    }
466
467    final ArrayList<PendingAssistExtras> mPendingAssistExtras
468            = new ArrayList<PendingAssistExtras>();
469
470    /**
471     * Process management.
472     */
473    final ProcessList mProcessList = new ProcessList();
474
475    /**
476     * All of the applications we currently have running organized by name.
477     * The keys are strings of the application package name (as
478     * returned by the package manager), and the keys are ApplicationRecord
479     * objects.
480     */
481    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
482
483    /**
484     * Tracking long-term execution of processes to look for abuse and other
485     * bad app behavior.
486     */
487    final ProcessStatsService mProcessStats;
488
489    /**
490     * The currently running isolated processes.
491     */
492    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
493
494    /**
495     * Counter for assigning isolated process uids, to avoid frequently reusing the
496     * same ones.
497     */
498    int mNextIsolatedProcessUid = 0;
499
500    /**
501     * The currently running heavy-weight process, if any.
502     */
503    ProcessRecord mHeavyWeightProcess = null;
504
505    /**
506     * The last time that various processes have crashed.
507     */
508    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
509
510    /**
511     * Information about a process that is currently marked as bad.
512     */
513    static final class BadProcessInfo {
514        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
515            this.time = time;
516            this.shortMsg = shortMsg;
517            this.longMsg = longMsg;
518            this.stack = stack;
519        }
520
521        final long time;
522        final String shortMsg;
523        final String longMsg;
524        final String stack;
525    }
526
527    /**
528     * Set of applications that we consider to be bad, and will reject
529     * incoming broadcasts from (which the user has no control over).
530     * Processes are added to this set when they have crashed twice within
531     * a minimum amount of time; they are removed from it when they are
532     * later restarted (hopefully due to some user action).  The value is the
533     * time it was added to the list.
534     */
535    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
536
537    /**
538     * All of the processes we currently have running organized by pid.
539     * The keys are the pid running the application.
540     *
541     * <p>NOTE: This object is protected by its own lock, NOT the global
542     * activity manager lock!
543     */
544    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
545
546    /**
547     * All of the processes that have been forced to be foreground.  The key
548     * is the pid of the caller who requested it (we hold a death
549     * link on it).
550     */
551    abstract class ForegroundToken implements IBinder.DeathRecipient {
552        int pid;
553        IBinder token;
554    }
555    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
556
557    /**
558     * List of records for processes that someone had tried to start before the
559     * system was ready.  We don't start them at that point, but ensure they
560     * are started by the time booting is complete.
561     */
562    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
563
564    /**
565     * List of persistent applications that are in the process
566     * of being started.
567     */
568    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes that are being forcibly torn down.
572     */
573    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * List of running applications, sorted by recent usage.
577     * The first entry in the list is the least recently used.
578     */
579    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
580
581    /**
582     * Where in mLruProcesses that the processes hosting activities start.
583     */
584    int mLruProcessActivityStart = 0;
585
586    /**
587     * Where in mLruProcesses that the processes hosting services start.
588     * This is after (lower index) than mLruProcessesActivityStart.
589     */
590    int mLruProcessServiceStart = 0;
591
592    /**
593     * List of processes that should gc as soon as things are idle.
594     */
595    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
596
597    /**
598     * Processes we want to collect PSS data from.
599     */
600    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
601
602    /**
603     * Last time we requested PSS data of all processes.
604     */
605    long mLastFullPssTime = SystemClock.uptimeMillis();
606
607    /**
608     * If set, the next time we collect PSS data we should do a full collection
609     * with data from native processes and the kernel.
610     */
611    boolean mFullPssPending = false;
612
613    /**
614     * This is the process holding what we currently consider to be
615     * the "home" activity.
616     */
617    ProcessRecord mHomeProcess;
618
619    /**
620     * This is the process holding the activity the user last visited that
621     * is in a different process from the one they are currently in.
622     */
623    ProcessRecord mPreviousProcess;
624
625    /**
626     * The time at which the previous process was last visible.
627     */
628    long mPreviousProcessVisibleTime;
629
630    /**
631     * Which uses have been started, so are allowed to run code.
632     */
633    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
634
635    /**
636     * LRU list of history of current users.  Most recently current is at the end.
637     */
638    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
639
640    /**
641     * Constant array of the users that are currently started.
642     */
643    int[] mStartedUserArray = new int[] { 0 };
644
645    /**
646     * Registered observers of the user switching mechanics.
647     */
648    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
649            = new RemoteCallbackList<IUserSwitchObserver>();
650
651    /**
652     * Currently active user switch.
653     */
654    Object mCurUserSwitchCallback;
655
656    /**
657     * Packages that the user has asked to have run in screen size
658     * compatibility mode instead of filling the screen.
659     */
660    final CompatModePackages mCompatModePackages;
661
662    /**
663     * Set of IntentSenderRecord objects that are currently active.
664     */
665    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
666            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
667
668    /**
669     * Fingerprints (hashCode()) of stack traces that we've
670     * already logged DropBox entries for.  Guarded by itself.  If
671     * something (rogue user app) forces this over
672     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
673     */
674    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
675    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
676
677    /**
678     * Strict Mode background batched logging state.
679     *
680     * The string buffer is guarded by itself, and its lock is also
681     * used to determine if another batched write is already
682     * in-flight.
683     */
684    private final StringBuilder mStrictModeBuffer = new StringBuilder();
685
686    /**
687     * Keeps track of all IIntentReceivers that have been registered for
688     * broadcasts.  Hash keys are the receiver IBinder, hash value is
689     * a ReceiverList.
690     */
691    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
692            new HashMap<IBinder, ReceiverList>();
693
694    /**
695     * Resolver for broadcast intents to registered receivers.
696     * Holds BroadcastFilter (subclass of IntentFilter).
697     */
698    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
699            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
700        @Override
701        protected boolean allowFilterResult(
702                BroadcastFilter filter, List<BroadcastFilter> dest) {
703            IBinder target = filter.receiverList.receiver.asBinder();
704            for (int i=dest.size()-1; i>=0; i--) {
705                if (dest.get(i).receiverList.receiver.asBinder() == target) {
706                    return false;
707                }
708            }
709            return true;
710        }
711
712        @Override
713        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
714            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
715                    || userId == filter.owningUserId) {
716                return super.newResult(filter, match, userId);
717            }
718            return null;
719        }
720
721        @Override
722        protected BroadcastFilter[] newArray(int size) {
723            return new BroadcastFilter[size];
724        }
725
726        @Override
727        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
728            return packageName.equals(filter.packageName);
729        }
730    };
731
732    /**
733     * State of all active sticky broadcasts per user.  Keys are the action of the
734     * sticky Intent, values are an ArrayList of all broadcasted intents with
735     * that action (which should usually be one).  The SparseArray is keyed
736     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
737     * for stickies that are sent to all users.
738     */
739    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
740            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
741
742    final ActiveServices mServices;
743
744    final static class Association {
745        final int mSourceUid;
746        final String mSourceProcess;
747        final int mTargetUid;
748        final ComponentName mTargetComponent;
749        final String mTargetProcess;
750
751        int mCount;
752        long mTime;
753
754        int mNesting;
755        long mStartTime;
756
757        Association(int sourceUid, String sourceProcess, int targetUid,
758                ComponentName targetComponent, String targetProcess) {
759            mSourceUid = sourceUid;
760            mSourceProcess = sourceProcess;
761            mTargetUid = targetUid;
762            mTargetComponent = targetComponent;
763            mTargetProcess = targetProcess;
764        }
765    }
766
767    /**
768     * When service association tracking is enabled, this is all of the associations we
769     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
770     * -> association data.
771     */
772    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
773            mAssociations = new SparseArray<>();
774    boolean mTrackingAssociations;
775
776    /**
777     * Backup/restore process management
778     */
779    String mBackupAppName = null;
780    BackupRecord mBackupTarget = null;
781
782    final ProviderMap mProviderMap;
783
784    /**
785     * List of content providers who have clients waiting for them.  The
786     * application is currently being launched and the provider will be
787     * removed from this list once it is published.
788     */
789    final ArrayList<ContentProviderRecord> mLaunchingProviders
790            = new ArrayList<ContentProviderRecord>();
791
792    /**
793     * File storing persisted {@link #mGrantedUriPermissions}.
794     */
795    private final AtomicFile mGrantFile;
796
797    /** XML constants used in {@link #mGrantFile} */
798    private static final String TAG_URI_GRANTS = "uri-grants";
799    private static final String TAG_URI_GRANT = "uri-grant";
800    private static final String ATTR_USER_HANDLE = "userHandle";
801    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
802    private static final String ATTR_TARGET_USER_ID = "targetUserId";
803    private static final String ATTR_SOURCE_PKG = "sourcePkg";
804    private static final String ATTR_TARGET_PKG = "targetPkg";
805    private static final String ATTR_URI = "uri";
806    private static final String ATTR_MODE_FLAGS = "modeFlags";
807    private static final String ATTR_CREATED_TIME = "createdTime";
808    private static final String ATTR_PREFIX = "prefix";
809
810    /**
811     * Global set of specific {@link Uri} permissions that have been granted.
812     * This optimized lookup structure maps from {@link UriPermission#targetUid}
813     * to {@link UriPermission#uri} to {@link UriPermission}.
814     */
815    @GuardedBy("this")
816    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
817            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
818
819    public static class GrantUri {
820        public final int sourceUserId;
821        public final Uri uri;
822        public boolean prefix;
823
824        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
825            this.sourceUserId = sourceUserId;
826            this.uri = uri;
827            this.prefix = prefix;
828        }
829
830        @Override
831        public int hashCode() {
832            int hashCode = 1;
833            hashCode = 31 * hashCode + sourceUserId;
834            hashCode = 31 * hashCode + uri.hashCode();
835            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
836            return hashCode;
837        }
838
839        @Override
840        public boolean equals(Object o) {
841            if (o instanceof GrantUri) {
842                GrantUri other = (GrantUri) o;
843                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
844                        && prefix == other.prefix;
845            }
846            return false;
847        }
848
849        @Override
850        public String toString() {
851            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
852            if (prefix) result += " [prefix]";
853            return result;
854        }
855
856        public String toSafeString() {
857            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
858            if (prefix) result += " [prefix]";
859            return result;
860        }
861
862        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
863            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
864                    ContentProvider.getUriWithoutUserId(uri), false);
865        }
866    }
867
868    CoreSettingsObserver mCoreSettingsObserver;
869
870    /**
871     * Thread-local storage used to carry caller permissions over through
872     * indirect content-provider access.
873     */
874    private class Identity {
875        public final IBinder token;
876        public final int pid;
877        public final int uid;
878
879        Identity(IBinder _token, int _pid, int _uid) {
880            token = _token;
881            pid = _pid;
882            uid = _uid;
883        }
884    }
885
886    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
887
888    /**
889     * All information we have collected about the runtime performance of
890     * any user id that can impact battery performance.
891     */
892    final BatteryStatsService mBatteryStatsService;
893
894    /**
895     * Information about component usage
896     */
897    UsageStatsManagerInternal mUsageStatsService;
898
899    /**
900     * Information about and control over application operations
901     */
902    final AppOpsService mAppOpsService;
903
904    /**
905     * Save recent tasks information across reboots.
906     */
907    final TaskPersister mTaskPersister;
908
909    /**
910     * Current configuration information.  HistoryRecord objects are given
911     * a reference to this object to indicate which configuration they are
912     * currently running in, so this object must be kept immutable.
913     */
914    Configuration mConfiguration = new Configuration();
915
916    /**
917     * Current sequencing integer of the configuration, for skipping old
918     * configurations.
919     */
920    int mConfigurationSeq = 0;
921
922    /**
923     * Hardware-reported OpenGLES version.
924     */
925    final int GL_ES_VERSION;
926
927    /**
928     * List of initialization arguments to pass to all processes when binding applications to them.
929     * For example, references to the commonly used services.
930     */
931    HashMap<String, IBinder> mAppBindArgs;
932
933    /**
934     * Temporary to avoid allocations.  Protected by main lock.
935     */
936    final StringBuilder mStringBuilder = new StringBuilder(256);
937
938    /**
939     * Used to control how we initialize the service.
940     */
941    ComponentName mTopComponent;
942    String mTopAction = Intent.ACTION_MAIN;
943    String mTopData;
944    boolean mProcessesReady = false;
945    boolean mSystemReady = false;
946    boolean mBooting = false;
947    boolean mCallFinishBooting = false;
948    boolean mBootAnimationComplete = false;
949    boolean mWaitingUpdate = false;
950    boolean mDidUpdate = false;
951    boolean mOnBattery = false;
952    boolean mLaunchWarningShown = false;
953
954    Context mContext;
955
956    int mFactoryTest;
957
958    boolean mCheckedForSetup;
959
960    /**
961     * The time at which we will allow normal application switches again,
962     * after a call to {@link #stopAppSwitches()}.
963     */
964    long mAppSwitchesAllowedTime;
965
966    /**
967     * This is set to true after the first switch after mAppSwitchesAllowedTime
968     * is set; any switches after that will clear the time.
969     */
970    boolean mDidAppSwitch;
971
972    /**
973     * Last time (in realtime) at which we checked for power usage.
974     */
975    long mLastPowerCheckRealtime;
976
977    /**
978     * Last time (in uptime) at which we checked for power usage.
979     */
980    long mLastPowerCheckUptime;
981
982    /**
983     * Set while we are wanting to sleep, to prevent any
984     * activities from being started/resumed.
985     */
986    private boolean mSleeping = false;
987
988    /**
989     * Set while we are running a voice interaction.  This overrides
990     * sleeping while it is active.
991     */
992    private boolean mRunningVoice = false;
993
994    /**
995     * State of external calls telling us if the device is awake or asleep.
996     */
997    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
998
999    static final int LOCK_SCREEN_HIDDEN = 0;
1000    static final int LOCK_SCREEN_LEAVING = 1;
1001    static final int LOCK_SCREEN_SHOWN = 2;
1002    /**
1003     * State of external call telling us if the lock screen is shown.
1004     */
1005    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1006
1007    /**
1008     * Set if we are shutting down the system, similar to sleeping.
1009     */
1010    boolean mShuttingDown = false;
1011
1012    /**
1013     * Current sequence id for oom_adj computation traversal.
1014     */
1015    int mAdjSeq = 0;
1016
1017    /**
1018     * Current sequence id for process LRU updating.
1019     */
1020    int mLruSeq = 0;
1021
1022    /**
1023     * Keep track of the non-cached/empty process we last found, to help
1024     * determine how to distribute cached/empty processes next time.
1025     */
1026    int mNumNonCachedProcs = 0;
1027
1028    /**
1029     * Keep track of the number of cached hidden procs, to balance oom adj
1030     * distribution between those and empty procs.
1031     */
1032    int mNumCachedHiddenProcs = 0;
1033
1034    /**
1035     * Keep track of the number of service processes we last found, to
1036     * determine on the next iteration which should be B services.
1037     */
1038    int mNumServiceProcs = 0;
1039    int mNewNumAServiceProcs = 0;
1040    int mNewNumServiceProcs = 0;
1041
1042    /**
1043     * Allow the current computed overall memory level of the system to go down?
1044     * This is set to false when we are killing processes for reasons other than
1045     * memory management, so that the now smaller process list will not be taken as
1046     * an indication that memory is tighter.
1047     */
1048    boolean mAllowLowerMemLevel = false;
1049
1050    /**
1051     * The last computed memory level, for holding when we are in a state that
1052     * processes are going away for other reasons.
1053     */
1054    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1055
1056    /**
1057     * The last total number of process we have, to determine if changes actually look
1058     * like a shrinking number of process due to lower RAM.
1059     */
1060    int mLastNumProcesses;
1061
1062    /**
1063     * The uptime of the last time we performed idle maintenance.
1064     */
1065    long mLastIdleTime = SystemClock.uptimeMillis();
1066
1067    /**
1068     * Total time spent with RAM that has been added in the past since the last idle time.
1069     */
1070    long mLowRamTimeSinceLastIdle = 0;
1071
1072    /**
1073     * If RAM is currently low, when that horrible situation started.
1074     */
1075    long mLowRamStartTime = 0;
1076
1077    /**
1078     * For reporting to battery stats the current top application.
1079     */
1080    private String mCurResumedPackage = null;
1081    private int mCurResumedUid = -1;
1082
1083    /**
1084     * For reporting to battery stats the apps currently running foreground
1085     * service.  The ProcessMap is package/uid tuples; each of these contain
1086     * an array of the currently foreground processes.
1087     */
1088    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1089            = new ProcessMap<ArrayList<ProcessRecord>>();
1090
1091    /**
1092     * This is set if we had to do a delayed dexopt of an app before launching
1093     * it, to increase the ANR timeouts in that case.
1094     */
1095    boolean mDidDexOpt;
1096
1097    /**
1098     * Set if the systemServer made a call to enterSafeMode.
1099     */
1100    boolean mSafeMode;
1101
1102    /**
1103     * If true, we are running under a test environment so will sample PSS from processes
1104     * much more rapidly to try to collect better data when the tests are rapidly
1105     * running through apps.
1106     */
1107    boolean mTestPssMode = false;
1108
1109    String mDebugApp = null;
1110    boolean mWaitForDebugger = false;
1111    boolean mDebugTransient = false;
1112    String mOrigDebugApp = null;
1113    boolean mOrigWaitForDebugger = false;
1114    boolean mAlwaysFinishActivities = false;
1115    IActivityController mController = null;
1116    String mProfileApp = null;
1117    ProcessRecord mProfileProc = null;
1118    String mProfileFile;
1119    ParcelFileDescriptor mProfileFd;
1120    int mSamplingInterval = 0;
1121    boolean mAutoStopProfiler = false;
1122    int mProfileType = 0;
1123    String mOpenGlTraceApp = null;
1124
1125    final long[] mTmpLong = new long[1];
1126
1127    static class ProcessChangeItem {
1128        static final int CHANGE_ACTIVITIES = 1<<0;
1129        static final int CHANGE_PROCESS_STATE = 1<<1;
1130        int changes;
1131        int uid;
1132        int pid;
1133        int processState;
1134        boolean foregroundActivities;
1135    }
1136
1137    final RemoteCallbackList<IProcessObserver> mProcessObservers
1138            = new RemoteCallbackList<IProcessObserver>();
1139    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1140
1141    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1142            = new ArrayList<ProcessChangeItem>();
1143    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1144            = new ArrayList<ProcessChangeItem>();
1145
1146    /**
1147     * Runtime CPU use collection thread.  This object's lock is used to
1148     * perform synchronization with the thread (notifying it to run).
1149     */
1150    final Thread mProcessCpuThread;
1151
1152    /**
1153     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1154     * Must acquire this object's lock when accessing it.
1155     * NOTE: this lock will be held while doing long operations (trawling
1156     * through all processes in /proc), so it should never be acquired by
1157     * any critical paths such as when holding the main activity manager lock.
1158     */
1159    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1160            MONITOR_THREAD_CPU_USAGE);
1161    final AtomicLong mLastCpuTime = new AtomicLong(0);
1162    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1163
1164    long mLastWriteTime = 0;
1165
1166    /**
1167     * Used to retain an update lock when the foreground activity is in
1168     * immersive mode.
1169     */
1170    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1171
1172    /**
1173     * Set to true after the system has finished booting.
1174     */
1175    boolean mBooted = false;
1176
1177    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1178    int mProcessLimitOverride = -1;
1179
1180    WindowManagerService mWindowManager;
1181
1182    final ActivityThread mSystemThread;
1183
1184    // Holds the current foreground user's id
1185    int mCurrentUserId = 0;
1186    // Holds the target user's id during a user switch
1187    int mTargetUserId = UserHandle.USER_NULL;
1188    // If there are multiple profiles for the current user, their ids are here
1189    // Currently only the primary user can have managed profiles
1190    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1191
1192    /**
1193     * Mapping from each known user ID to the profile group ID it is associated with.
1194     */
1195    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1196
1197    private UserManagerService mUserManager;
1198
1199    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1200        final ProcessRecord mApp;
1201        final int mPid;
1202        final IApplicationThread mAppThread;
1203
1204        AppDeathRecipient(ProcessRecord app, int pid,
1205                IApplicationThread thread) {
1206            if (localLOGV) Slog.v(
1207                TAG, "New death recipient " + this
1208                + " for thread " + thread.asBinder());
1209            mApp = app;
1210            mPid = pid;
1211            mAppThread = thread;
1212        }
1213
1214        @Override
1215        public void binderDied() {
1216            if (localLOGV) Slog.v(
1217                TAG, "Death received in " + this
1218                + " for thread " + mAppThread.asBinder());
1219            synchronized(ActivityManagerService.this) {
1220                appDiedLocked(mApp, mPid, mAppThread, true);
1221            }
1222        }
1223    }
1224
1225    static final int SHOW_ERROR_MSG = 1;
1226    static final int SHOW_NOT_RESPONDING_MSG = 2;
1227    static final int SHOW_FACTORY_ERROR_MSG = 3;
1228    static final int UPDATE_CONFIGURATION_MSG = 4;
1229    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1230    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1231    static final int SERVICE_TIMEOUT_MSG = 12;
1232    static final int UPDATE_TIME_ZONE = 13;
1233    static final int SHOW_UID_ERROR_MSG = 14;
1234    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1235    static final int PROC_START_TIMEOUT_MSG = 20;
1236    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1237    static final int KILL_APPLICATION_MSG = 22;
1238    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1239    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1240    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1241    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1242    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1243    static final int CLEAR_DNS_CACHE_MSG = 28;
1244    static final int UPDATE_HTTP_PROXY_MSG = 29;
1245    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1246    static final int DISPATCH_PROCESSES_CHANGED = 31;
1247    static final int DISPATCH_PROCESS_DIED = 32;
1248    static final int REPORT_MEM_USAGE_MSG = 33;
1249    static final int REPORT_USER_SWITCH_MSG = 34;
1250    static final int CONTINUE_USER_SWITCH_MSG = 35;
1251    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1252    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1253    static final int PERSIST_URI_GRANTS_MSG = 38;
1254    static final int REQUEST_ALL_PSS_MSG = 39;
1255    static final int START_PROFILES_MSG = 40;
1256    static final int UPDATE_TIME = 41;
1257    static final int SYSTEM_USER_START_MSG = 42;
1258    static final int SYSTEM_USER_CURRENT_MSG = 43;
1259    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1260    static final int FINISH_BOOTING_MSG = 45;
1261    static final int START_USER_SWITCH_MSG = 46;
1262    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1263    static final int DISMISS_DIALOG_MSG = 48;
1264    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1265    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1266
1267    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1268    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1269    static final int FIRST_COMPAT_MODE_MSG = 300;
1270    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1271
1272    CompatModeDialog mCompatModeDialog;
1273    long mLastMemUsageReportTime = 0;
1274
1275    /**
1276     * Flag whether the current user is a "monkey", i.e. whether
1277     * the UI is driven by a UI automation tool.
1278     */
1279    private boolean mUserIsMonkey;
1280
1281    /** Flag whether the device has a Recents UI */
1282    boolean mHasRecents;
1283
1284    /** The dimensions of the thumbnails in the Recents UI. */
1285    int mThumbnailWidth;
1286    int mThumbnailHeight;
1287
1288    final ServiceThread mHandlerThread;
1289    final MainHandler mHandler;
1290
1291    final class MainHandler extends Handler {
1292        public MainHandler(Looper looper) {
1293            super(looper, null, true);
1294        }
1295
1296        @Override
1297        public void handleMessage(Message msg) {
1298            switch (msg.what) {
1299            case SHOW_ERROR_MSG: {
1300                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1301                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1302                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1303                synchronized (ActivityManagerService.this) {
1304                    ProcessRecord proc = (ProcessRecord)data.get("app");
1305                    AppErrorResult res = (AppErrorResult) data.get("result");
1306                    if (proc != null && proc.crashDialog != null) {
1307                        Slog.e(TAG, "App already has crash dialog: " + proc);
1308                        if (res != null) {
1309                            res.set(0);
1310                        }
1311                        return;
1312                    }
1313                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1314                            >= Process.FIRST_APPLICATION_UID
1315                            && proc.pid != MY_PID);
1316                    for (int userId : mCurrentProfileIds) {
1317                        isBackground &= (proc.userId != userId);
1318                    }
1319                    if (isBackground && !showBackground) {
1320                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1321                        if (res != null) {
1322                            res.set(0);
1323                        }
1324                        return;
1325                    }
1326                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1327                        Dialog d = new AppErrorDialog(mContext,
1328                                ActivityManagerService.this, res, proc);
1329                        d.show();
1330                        proc.crashDialog = d;
1331                    } else {
1332                        // The device is asleep, so just pretend that the user
1333                        // saw a crash dialog and hit "force quit".
1334                        if (res != null) {
1335                            res.set(0);
1336                        }
1337                    }
1338                }
1339
1340                ensureBootCompleted();
1341            } break;
1342            case SHOW_NOT_RESPONDING_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1345                    ProcessRecord proc = (ProcessRecord)data.get("app");
1346                    if (proc != null && proc.anrDialog != null) {
1347                        Slog.e(TAG, "App already has anr dialog: " + proc);
1348                        return;
1349                    }
1350
1351                    Intent intent = new Intent("android.intent.action.ANR");
1352                    if (!mProcessesReady) {
1353                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1354                                | Intent.FLAG_RECEIVER_FOREGROUND);
1355                    }
1356                    broadcastIntentLocked(null, null, intent,
1357                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1358                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1359
1360                    if (mShowDialogs) {
1361                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1362                                mContext, proc, (ActivityRecord)data.get("activity"),
1363                                msg.arg1 != 0);
1364                        d.show();
1365                        proc.anrDialog = d;
1366                    } else {
1367                        // Just kill the app if there is no dialog to be shown.
1368                        killAppAtUsersRequest(proc, null);
1369                    }
1370                }
1371
1372                ensureBootCompleted();
1373            } break;
1374            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1375                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1376                synchronized (ActivityManagerService.this) {
1377                    ProcessRecord proc = (ProcessRecord) data.get("app");
1378                    if (proc == null) {
1379                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1380                        break;
1381                    }
1382                    if (proc.crashDialog != null) {
1383                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1384                        return;
1385                    }
1386                    AppErrorResult res = (AppErrorResult) data.get("result");
1387                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1388                        Dialog d = new StrictModeViolationDialog(mContext,
1389                                ActivityManagerService.this, res, proc);
1390                        d.show();
1391                        proc.crashDialog = d;
1392                    } else {
1393                        // The device is asleep, so just pretend that the user
1394                        // saw a crash dialog and hit "force quit".
1395                        res.set(0);
1396                    }
1397                }
1398                ensureBootCompleted();
1399            } break;
1400            case SHOW_FACTORY_ERROR_MSG: {
1401                Dialog d = new FactoryErrorDialog(
1402                    mContext, msg.getData().getCharSequence("msg"));
1403                d.show();
1404                ensureBootCompleted();
1405            } break;
1406            case UPDATE_CONFIGURATION_MSG: {
1407                final ContentResolver resolver = mContext.getContentResolver();
1408                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1409            } break;
1410            case GC_BACKGROUND_PROCESSES_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    performAppGcsIfAppropriateLocked();
1413                }
1414            } break;
1415            case WAIT_FOR_DEBUGGER_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    ProcessRecord app = (ProcessRecord)msg.obj;
1418                    if (msg.arg1 != 0) {
1419                        if (!app.waitedForDebugger) {
1420                            Dialog d = new AppWaitingForDebuggerDialog(
1421                                    ActivityManagerService.this,
1422                                    mContext, app);
1423                            app.waitDialog = d;
1424                            app.waitedForDebugger = true;
1425                            d.show();
1426                        }
1427                    } else {
1428                        if (app.waitDialog != null) {
1429                            app.waitDialog.dismiss();
1430                            app.waitDialog = null;
1431                        }
1432                    }
1433                }
1434            } break;
1435            case SERVICE_TIMEOUT_MSG: {
1436                if (mDidDexOpt) {
1437                    mDidDexOpt = false;
1438                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1439                    nmsg.obj = msg.obj;
1440                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1441                    return;
1442                }
1443                mServices.serviceTimeout((ProcessRecord)msg.obj);
1444            } break;
1445            case UPDATE_TIME_ZONE: {
1446                synchronized (ActivityManagerService.this) {
1447                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1448                        ProcessRecord r = mLruProcesses.get(i);
1449                        if (r.thread != null) {
1450                            try {
1451                                r.thread.updateTimeZone();
1452                            } catch (RemoteException ex) {
1453                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1454                            }
1455                        }
1456                    }
1457                }
1458            } break;
1459            case CLEAR_DNS_CACHE_MSG: {
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.clearDnsCache();
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1468                            }
1469                        }
1470                    }
1471                }
1472            } break;
1473            case UPDATE_HTTP_PROXY_MSG: {
1474                ProxyInfo proxy = (ProxyInfo)msg.obj;
1475                String host = "";
1476                String port = "";
1477                String exclList = "";
1478                Uri pacFileUrl = Uri.EMPTY;
1479                if (proxy != null) {
1480                    host = proxy.getHost();
1481                    port = Integer.toString(proxy.getPort());
1482                    exclList = proxy.getExclusionListAsString();
1483                    pacFileUrl = proxy.getPacFileUrl();
1484                }
1485                synchronized (ActivityManagerService.this) {
1486                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1487                        ProcessRecord r = mLruProcesses.get(i);
1488                        if (r.thread != null) {
1489                            try {
1490                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1491                            } catch (RemoteException ex) {
1492                                Slog.w(TAG, "Failed to update http proxy for: " +
1493                                        r.info.processName);
1494                            }
1495                        }
1496                    }
1497                }
1498            } break;
1499            case SHOW_UID_ERROR_MSG: {
1500                if (mShowDialogs) {
1501                    AlertDialog d = new BaseErrorDialog(mContext);
1502                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1503                    d.setCancelable(false);
1504                    d.setTitle(mContext.getText(R.string.android_system_label));
1505                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1506                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1507                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1508                    d.show();
1509                }
1510            } break;
1511            case SHOW_FINGERPRINT_ERROR_MSG: {
1512                if (mShowDialogs) {
1513                    AlertDialog d = new BaseErrorDialog(mContext);
1514                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1515                    d.setCancelable(false);
1516                    d.setTitle(mContext.getText(R.string.android_system_label));
1517                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1518                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1519                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1520                    d.show();
1521                }
1522            } break;
1523            case PROC_START_TIMEOUT_MSG: {
1524                if (mDidDexOpt) {
1525                    mDidDexOpt = false;
1526                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1527                    nmsg.obj = msg.obj;
1528                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1529                    return;
1530                }
1531                ProcessRecord app = (ProcessRecord)msg.obj;
1532                synchronized (ActivityManagerService.this) {
1533                    processStartTimedOutLocked(app);
1534                }
1535            } break;
1536            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1537                synchronized (ActivityManagerService.this) {
1538                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1539                }
1540            } break;
1541            case KILL_APPLICATION_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    int appid = msg.arg1;
1544                    boolean restart = (msg.arg2 == 1);
1545                    Bundle bundle = (Bundle)msg.obj;
1546                    String pkg = bundle.getString("pkg");
1547                    String reason = bundle.getString("reason");
1548                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1549                            false, UserHandle.USER_ALL, reason);
1550                }
1551            } break;
1552            case FINALIZE_PENDING_INTENT_MSG: {
1553                ((PendingIntentRecord)msg.obj).completeFinalize();
1554            } break;
1555            case POST_HEAVY_NOTIFICATION_MSG: {
1556                INotificationManager inm = NotificationManager.getService();
1557                if (inm == null) {
1558                    return;
1559                }
1560
1561                ActivityRecord root = (ActivityRecord)msg.obj;
1562                ProcessRecord process = root.app;
1563                if (process == null) {
1564                    return;
1565                }
1566
1567                try {
1568                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1569                    String text = mContext.getString(R.string.heavy_weight_notification,
1570                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1571                    Notification notification = new Notification();
1572                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1573                    notification.when = 0;
1574                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1575                    notification.tickerText = text;
1576                    notification.defaults = 0; // please be quiet
1577                    notification.sound = null;
1578                    notification.vibrate = null;
1579                    notification.color = mContext.getResources().getColor(
1580                            com.android.internal.R.color.system_notification_accent_color);
1581                    notification.setLatestEventInfo(context, text,
1582                            mContext.getText(R.string.heavy_weight_notification_detail),
1583                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1584                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1585                                    new UserHandle(root.userId)));
1586
1587                    try {
1588                        int[] outId = new int[1];
1589                        inm.enqueueNotificationWithTag("android", "android", null,
1590                                R.string.heavy_weight_notification,
1591                                notification, outId, root.userId);
1592                    } catch (RuntimeException e) {
1593                        Slog.w(ActivityManagerService.TAG,
1594                                "Error showing notification for heavy-weight app", e);
1595                    } catch (RemoteException e) {
1596                    }
1597                } catch (NameNotFoundException e) {
1598                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1599                }
1600            } break;
1601            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1602                INotificationManager inm = NotificationManager.getService();
1603                if (inm == null) {
1604                    return;
1605                }
1606                try {
1607                    inm.cancelNotificationWithTag("android", null,
1608                            R.string.heavy_weight_notification,  msg.arg1);
1609                } catch (RuntimeException e) {
1610                    Slog.w(ActivityManagerService.TAG,
1611                            "Error canceling notification for service", e);
1612                } catch (RemoteException e) {
1613                }
1614            } break;
1615            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1616                synchronized (ActivityManagerService.this) {
1617                    checkExcessivePowerUsageLocked(true);
1618                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1619                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1620                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1621                }
1622            } break;
1623            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1624                synchronized (ActivityManagerService.this) {
1625                    ActivityRecord ar = (ActivityRecord)msg.obj;
1626                    if (mCompatModeDialog != null) {
1627                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1628                                ar.info.applicationInfo.packageName)) {
1629                            return;
1630                        }
1631                        mCompatModeDialog.dismiss();
1632                        mCompatModeDialog = null;
1633                    }
1634                    if (ar != null && false) {
1635                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1636                                ar.packageName)) {
1637                            int mode = mCompatModePackages.computeCompatModeLocked(
1638                                    ar.info.applicationInfo);
1639                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1640                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1641                                mCompatModeDialog = new CompatModeDialog(
1642                                        ActivityManagerService.this, mContext,
1643                                        ar.info.applicationInfo);
1644                                mCompatModeDialog.show();
1645                            }
1646                        }
1647                    }
1648                }
1649                break;
1650            }
1651            case DISPATCH_PROCESSES_CHANGED: {
1652                dispatchProcessesChanged();
1653                break;
1654            }
1655            case DISPATCH_PROCESS_DIED: {
1656                final int pid = msg.arg1;
1657                final int uid = msg.arg2;
1658                dispatchProcessDied(pid, uid);
1659                break;
1660            }
1661            case REPORT_MEM_USAGE_MSG: {
1662                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1663                Thread thread = new Thread() {
1664                    @Override public void run() {
1665                        reportMemUsage(memInfos);
1666                    }
1667                };
1668                thread.start();
1669                break;
1670            }
1671            case START_USER_SWITCH_MSG: {
1672                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1673                break;
1674            }
1675            case REPORT_USER_SWITCH_MSG: {
1676                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1677                break;
1678            }
1679            case CONTINUE_USER_SWITCH_MSG: {
1680                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1681                break;
1682            }
1683            case USER_SWITCH_TIMEOUT_MSG: {
1684                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1685                break;
1686            }
1687            case IMMERSIVE_MODE_LOCK_MSG: {
1688                final boolean nextState = (msg.arg1 != 0);
1689                if (mUpdateLock.isHeld() != nextState) {
1690                    if (DEBUG_IMMERSIVE) {
1691                        final ActivityRecord r = (ActivityRecord) msg.obj;
1692                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1693                    }
1694                    if (nextState) {
1695                        mUpdateLock.acquire();
1696                    } else {
1697                        mUpdateLock.release();
1698                    }
1699                }
1700                break;
1701            }
1702            case PERSIST_URI_GRANTS_MSG: {
1703                writeGrantedUriPermissions();
1704                break;
1705            }
1706            case REQUEST_ALL_PSS_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1709                }
1710                break;
1711            }
1712            case START_PROFILES_MSG: {
1713                synchronized (ActivityManagerService.this) {
1714                    startProfilesLocked();
1715                }
1716                break;
1717            }
1718            case UPDATE_TIME: {
1719                synchronized (ActivityManagerService.this) {
1720                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1721                        ProcessRecord r = mLruProcesses.get(i);
1722                        if (r.thread != null) {
1723                            try {
1724                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1725                            } catch (RemoteException ex) {
1726                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1727                            }
1728                        }
1729                    }
1730                }
1731                break;
1732            }
1733            case SYSTEM_USER_START_MSG: {
1734                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1735                        Integer.toString(msg.arg1), msg.arg1);
1736                mSystemServiceManager.startUser(msg.arg1);
1737                break;
1738            }
1739            case SYSTEM_USER_CURRENT_MSG: {
1740                mBatteryStatsService.noteEvent(
1741                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1742                        Integer.toString(msg.arg2), msg.arg2);
1743                mBatteryStatsService.noteEvent(
1744                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1745                        Integer.toString(msg.arg1), msg.arg1);
1746                mSystemServiceManager.switchUser(msg.arg1);
1747                break;
1748            }
1749            case ENTER_ANIMATION_COMPLETE_MSG: {
1750                synchronized (ActivityManagerService.this) {
1751                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1752                    if (r != null && r.app != null && r.app.thread != null) {
1753                        try {
1754                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1755                        } catch (RemoteException e) {
1756                        }
1757                    }
1758                }
1759                break;
1760            }
1761            case FINISH_BOOTING_MSG: {
1762                if (msg.arg1 != 0) {
1763                    finishBooting();
1764                }
1765                if (msg.arg2 != 0) {
1766                    enableScreenAfterBoot();
1767                }
1768                break;
1769            }
1770            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1771                try {
1772                    Locale l = (Locale) msg.obj;
1773                    IBinder service = ServiceManager.getService("mount");
1774                    IMountService mountService = IMountService.Stub.asInterface(service);
1775                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1776                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1777                } catch (RemoteException e) {
1778                    Log.e(TAG, "Error storing locale for decryption UI", e);
1779                }
1780                break;
1781            }
1782            case DISMISS_DIALOG_MSG: {
1783                final Dialog d = (Dialog) msg.obj;
1784                d.dismiss();
1785                break;
1786            }
1787            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    int i = mTaskStackListeners.beginBroadcast();
1790                    while (i > 0) {
1791                        i--;
1792                        try {
1793                            // Make a one-way callback to the listener
1794                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1795                        } catch (RemoteException e){
1796                            // Handled by the RemoteCallbackList
1797                        }
1798                    }
1799                    mTaskStackListeners.finishBroadcast();
1800                }
1801                break;
1802            }
1803            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1804                final int uid = msg.arg1;
1805                final byte[] firstPacket = (byte[]) msg.obj;
1806
1807                synchronized (mPidsSelfLocked) {
1808                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1809                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1810                        if (p.uid == uid) {
1811                            try {
1812                                p.thread.notifyCleartextNetwork(firstPacket);
1813                            } catch (RemoteException ignored) {
1814                            }
1815                        }
1816                    }
1817                }
1818                break;
1819            }
1820            }
1821        }
1822    };
1823
1824    static final int COLLECT_PSS_BG_MSG = 1;
1825
1826    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1827        @Override
1828        public void handleMessage(Message msg) {
1829            switch (msg.what) {
1830            case COLLECT_PSS_BG_MSG: {
1831                long start = SystemClock.uptimeMillis();
1832                MemInfoReader memInfo = null;
1833                synchronized (ActivityManagerService.this) {
1834                    if (mFullPssPending) {
1835                        mFullPssPending = false;
1836                        memInfo = new MemInfoReader();
1837                    }
1838                }
1839                if (memInfo != null) {
1840                    updateCpuStatsNow();
1841                    long nativeTotalPss = 0;
1842                    synchronized (mProcessCpuTracker) {
1843                        final int N = mProcessCpuTracker.countStats();
1844                        for (int j=0; j<N; j++) {
1845                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1846                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1847                                // This is definitely an application process; skip it.
1848                                continue;
1849                            }
1850                            synchronized (mPidsSelfLocked) {
1851                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1852                                    // This is one of our own processes; skip it.
1853                                    continue;
1854                                }
1855                            }
1856                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1857                        }
1858                    }
1859                    memInfo.readMemInfo();
1860                    synchronized (ActivityManagerService.this) {
1861                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1862                                + (SystemClock.uptimeMillis()-start) + "ms");
1863                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1864                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1865                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1866                    }
1867                }
1868
1869                int num = 0;
1870                long[] tmp = new long[1];
1871                do {
1872                    ProcessRecord proc;
1873                    int procState;
1874                    int pid;
1875                    long lastPssTime;
1876                    synchronized (ActivityManagerService.this) {
1877                        if (mPendingPssProcesses.size() <= 0) {
1878                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1879                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1880                            mPendingPssProcesses.clear();
1881                            return;
1882                        }
1883                        proc = mPendingPssProcesses.remove(0);
1884                        procState = proc.pssProcState;
1885                        lastPssTime = proc.lastPssTime;
1886                        if (proc.thread != null && procState == proc.setProcState
1887                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1888                                        < SystemClock.uptimeMillis()) {
1889                            pid = proc.pid;
1890                        } else {
1891                            proc = null;
1892                            pid = 0;
1893                        }
1894                    }
1895                    if (proc != null) {
1896                        long pss = Debug.getPss(pid, tmp, null);
1897                        synchronized (ActivityManagerService.this) {
1898                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1899                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1900                                num++;
1901                                recordPssSample(proc, procState, pss, tmp[0],
1902                                        SystemClock.uptimeMillis());
1903                            }
1904                        }
1905                    }
1906                } while (true);
1907            }
1908            }
1909        }
1910    };
1911
1912    public void setSystemProcess() {
1913        try {
1914            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1915            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1916            ServiceManager.addService("meminfo", new MemBinder(this));
1917            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1918            ServiceManager.addService("dbinfo", new DbBinder(this));
1919            if (MONITOR_CPU_USAGE) {
1920                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1921            }
1922            ServiceManager.addService("permission", new PermissionController(this));
1923            ServiceManager.addService("processinfo", new ProcessInfoService(this));
1924
1925            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1926                    "android", STOCK_PM_FLAGS);
1927            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1928
1929            synchronized (this) {
1930                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1931                app.persistent = true;
1932                app.pid = MY_PID;
1933                app.maxAdj = ProcessList.SYSTEM_ADJ;
1934                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1935                mProcessNames.put(app.processName, app.uid, app);
1936                synchronized (mPidsSelfLocked) {
1937                    mPidsSelfLocked.put(app.pid, app);
1938                }
1939                updateLruProcessLocked(app, false, null);
1940                updateOomAdjLocked();
1941            }
1942        } catch (PackageManager.NameNotFoundException e) {
1943            throw new RuntimeException(
1944                    "Unable to find android system package", e);
1945        }
1946    }
1947
1948    public void setWindowManager(WindowManagerService wm) {
1949        mWindowManager = wm;
1950        mStackSupervisor.setWindowManager(wm);
1951    }
1952
1953    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1954        mUsageStatsService = usageStatsManager;
1955    }
1956
1957    public void startObservingNativeCrashes() {
1958        final NativeCrashListener ncl = new NativeCrashListener(this);
1959        ncl.start();
1960    }
1961
1962    public IAppOpsService getAppOpsService() {
1963        return mAppOpsService;
1964    }
1965
1966    static class MemBinder extends Binder {
1967        ActivityManagerService mActivityManagerService;
1968        MemBinder(ActivityManagerService activityManagerService) {
1969            mActivityManagerService = activityManagerService;
1970        }
1971
1972        @Override
1973        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1974            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1975                    != PackageManager.PERMISSION_GRANTED) {
1976                pw.println("Permission Denial: can't dump meminfo from from pid="
1977                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1978                        + " without permission " + android.Manifest.permission.DUMP);
1979                return;
1980            }
1981
1982            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1983        }
1984    }
1985
1986    static class GraphicsBinder extends Binder {
1987        ActivityManagerService mActivityManagerService;
1988        GraphicsBinder(ActivityManagerService activityManagerService) {
1989            mActivityManagerService = activityManagerService;
1990        }
1991
1992        @Override
1993        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1994            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1995                    != PackageManager.PERMISSION_GRANTED) {
1996                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1997                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1998                        + " without permission " + android.Manifest.permission.DUMP);
1999                return;
2000            }
2001
2002            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2003        }
2004    }
2005
2006    static class DbBinder extends Binder {
2007        ActivityManagerService mActivityManagerService;
2008        DbBinder(ActivityManagerService activityManagerService) {
2009            mActivityManagerService = activityManagerService;
2010        }
2011
2012        @Override
2013        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2014            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2015                    != PackageManager.PERMISSION_GRANTED) {
2016                pw.println("Permission Denial: can't dump dbinfo from from pid="
2017                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2018                        + " without permission " + android.Manifest.permission.DUMP);
2019                return;
2020            }
2021
2022            mActivityManagerService.dumpDbInfo(fd, pw, args);
2023        }
2024    }
2025
2026    static class CpuBinder extends Binder {
2027        ActivityManagerService mActivityManagerService;
2028        CpuBinder(ActivityManagerService activityManagerService) {
2029            mActivityManagerService = activityManagerService;
2030        }
2031
2032        @Override
2033        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2034            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2035                    != PackageManager.PERMISSION_GRANTED) {
2036                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2037                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2038                        + " without permission " + android.Manifest.permission.DUMP);
2039                return;
2040            }
2041
2042            synchronized (mActivityManagerService.mProcessCpuTracker) {
2043                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2044                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2045                        SystemClock.uptimeMillis()));
2046            }
2047        }
2048    }
2049
2050    public static final class Lifecycle extends SystemService {
2051        private final ActivityManagerService mService;
2052
2053        public Lifecycle(Context context) {
2054            super(context);
2055            mService = new ActivityManagerService(context);
2056        }
2057
2058        @Override
2059        public void onStart() {
2060            mService.start();
2061        }
2062
2063        public ActivityManagerService getService() {
2064            return mService;
2065        }
2066    }
2067
2068    // Note: This method is invoked on the main thread but may need to attach various
2069    // handlers to other threads.  So take care to be explicit about the looper.
2070    public ActivityManagerService(Context systemContext) {
2071        mContext = systemContext;
2072        mFactoryTest = FactoryTest.getMode();
2073        mSystemThread = ActivityThread.currentActivityThread();
2074
2075        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2076
2077        mHandlerThread = new ServiceThread(TAG,
2078                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2079        mHandlerThread.start();
2080        mHandler = new MainHandler(mHandlerThread.getLooper());
2081
2082        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2083                "foreground", BROADCAST_FG_TIMEOUT, false);
2084        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2085                "background", BROADCAST_BG_TIMEOUT, true);
2086        mBroadcastQueues[0] = mFgBroadcastQueue;
2087        mBroadcastQueues[1] = mBgBroadcastQueue;
2088
2089        mServices = new ActiveServices(this);
2090        mProviderMap = new ProviderMap(this);
2091
2092        // TODO: Move creation of battery stats service outside of activity manager service.
2093        File dataDir = Environment.getDataDirectory();
2094        File systemDir = new File(dataDir, "system");
2095        systemDir.mkdirs();
2096        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2097        mBatteryStatsService.getActiveStatistics().readLocked();
2098        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2099        mOnBattery = DEBUG_POWER ? true
2100                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2101        mBatteryStatsService.getActiveStatistics().setCallback(this);
2102
2103        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2104
2105        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2106
2107        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2108
2109        // User 0 is the first and only user that runs at boot.
2110        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2111        mUserLru.add(Integer.valueOf(0));
2112        updateStartedUserArrayLocked();
2113
2114        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2115            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2116
2117        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2118
2119        mConfiguration.setToDefaults();
2120        mConfiguration.locale = Locale.getDefault();
2121
2122        mConfigurationSeq = mConfiguration.seq = 1;
2123        mProcessCpuTracker.init();
2124
2125        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2126        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2127        mStackSupervisor = new ActivityStackSupervisor(this);
2128        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2129
2130        mProcessCpuThread = new Thread("CpuTracker") {
2131            @Override
2132            public void run() {
2133                while (true) {
2134                    try {
2135                        try {
2136                            synchronized(this) {
2137                                final long now = SystemClock.uptimeMillis();
2138                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2139                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2140                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2141                                //        + ", write delay=" + nextWriteDelay);
2142                                if (nextWriteDelay < nextCpuDelay) {
2143                                    nextCpuDelay = nextWriteDelay;
2144                                }
2145                                if (nextCpuDelay > 0) {
2146                                    mProcessCpuMutexFree.set(true);
2147                                    this.wait(nextCpuDelay);
2148                                }
2149                            }
2150                        } catch (InterruptedException e) {
2151                        }
2152                        updateCpuStatsNow();
2153                    } catch (Exception e) {
2154                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2155                    }
2156                }
2157            }
2158        };
2159
2160        Watchdog.getInstance().addMonitor(this);
2161        Watchdog.getInstance().addThread(mHandler);
2162    }
2163
2164    public void setSystemServiceManager(SystemServiceManager mgr) {
2165        mSystemServiceManager = mgr;
2166    }
2167
2168    public void setInstaller(Installer installer) {
2169        mInstaller = installer;
2170    }
2171
2172    private void start() {
2173        Process.removeAllProcessGroups();
2174        mProcessCpuThread.start();
2175
2176        mBatteryStatsService.publish(mContext);
2177        mAppOpsService.publish(mContext);
2178        Slog.d("AppOps", "AppOpsService published");
2179        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2180    }
2181
2182    public void initPowerManagement() {
2183        mStackSupervisor.initPowerManagement();
2184        mBatteryStatsService.initPowerManagement();
2185    }
2186
2187    @Override
2188    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2189            throws RemoteException {
2190        if (code == SYSPROPS_TRANSACTION) {
2191            // We need to tell all apps about the system property change.
2192            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2193            synchronized(this) {
2194                final int NP = mProcessNames.getMap().size();
2195                for (int ip=0; ip<NP; ip++) {
2196                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2197                    final int NA = apps.size();
2198                    for (int ia=0; ia<NA; ia++) {
2199                        ProcessRecord app = apps.valueAt(ia);
2200                        if (app.thread != null) {
2201                            procs.add(app.thread.asBinder());
2202                        }
2203                    }
2204                }
2205            }
2206
2207            int N = procs.size();
2208            for (int i=0; i<N; i++) {
2209                Parcel data2 = Parcel.obtain();
2210                try {
2211                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2212                } catch (RemoteException e) {
2213                }
2214                data2.recycle();
2215            }
2216        }
2217        try {
2218            return super.onTransact(code, data, reply, flags);
2219        } catch (RuntimeException e) {
2220            // The activity manager only throws security exceptions, so let's
2221            // log all others.
2222            if (!(e instanceof SecurityException)) {
2223                Slog.wtf(TAG, "Activity Manager Crash", e);
2224            }
2225            throw e;
2226        }
2227    }
2228
2229    void updateCpuStats() {
2230        final long now = SystemClock.uptimeMillis();
2231        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2232            return;
2233        }
2234        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2235            synchronized (mProcessCpuThread) {
2236                mProcessCpuThread.notify();
2237            }
2238        }
2239    }
2240
2241    void updateCpuStatsNow() {
2242        synchronized (mProcessCpuTracker) {
2243            mProcessCpuMutexFree.set(false);
2244            final long now = SystemClock.uptimeMillis();
2245            boolean haveNewCpuStats = false;
2246
2247            if (MONITOR_CPU_USAGE &&
2248                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2249                mLastCpuTime.set(now);
2250                haveNewCpuStats = true;
2251                mProcessCpuTracker.update();
2252                //Slog.i(TAG, mProcessCpu.printCurrentState());
2253                //Slog.i(TAG, "Total CPU usage: "
2254                //        + mProcessCpu.getTotalCpuPercent() + "%");
2255
2256                // Slog the cpu usage if the property is set.
2257                if ("true".equals(SystemProperties.get("events.cpu"))) {
2258                    int user = mProcessCpuTracker.getLastUserTime();
2259                    int system = mProcessCpuTracker.getLastSystemTime();
2260                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2261                    int irq = mProcessCpuTracker.getLastIrqTime();
2262                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2263                    int idle = mProcessCpuTracker.getLastIdleTime();
2264
2265                    int total = user + system + iowait + irq + softIrq + idle;
2266                    if (total == 0) total = 1;
2267
2268                    EventLog.writeEvent(EventLogTags.CPU,
2269                            ((user+system+iowait+irq+softIrq) * 100) / total,
2270                            (user * 100) / total,
2271                            (system * 100) / total,
2272                            (iowait * 100) / total,
2273                            (irq * 100) / total,
2274                            (softIrq * 100) / total);
2275                }
2276            }
2277
2278            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2279            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2280            synchronized(bstats) {
2281                synchronized(mPidsSelfLocked) {
2282                    if (haveNewCpuStats) {
2283                        if (mOnBattery) {
2284                            int perc = bstats.startAddingCpuLocked();
2285                            int totalUTime = 0;
2286                            int totalSTime = 0;
2287                            final int N = mProcessCpuTracker.countStats();
2288                            for (int i=0; i<N; i++) {
2289                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2290                                if (!st.working) {
2291                                    continue;
2292                                }
2293                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2294                                int otherUTime = (st.rel_utime*perc)/100;
2295                                int otherSTime = (st.rel_stime*perc)/100;
2296                                totalUTime += otherUTime;
2297                                totalSTime += otherSTime;
2298                                if (pr != null) {
2299                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2302                                                pr.info.uid, pr.processName);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2308                                } else {
2309                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2312                                                bstats.mapUid(st.uid), st.name);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                }
2318                            }
2319                            bstats.finishAddingCpuLocked(perc, totalUTime,
2320                                    totalSTime, cpuSpeedTimes);
2321                        }
2322                    }
2323                }
2324
2325                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2326                    mLastWriteTime = now;
2327                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2328                }
2329            }
2330        }
2331    }
2332
2333    @Override
2334    public void batteryNeedsCpuUpdate() {
2335        updateCpuStatsNow();
2336    }
2337
2338    @Override
2339    public void batteryPowerChanged(boolean onBattery) {
2340        // When plugging in, update the CPU stats first before changing
2341        // the plug state.
2342        updateCpuStatsNow();
2343        synchronized (this) {
2344            synchronized(mPidsSelfLocked) {
2345                mOnBattery = DEBUG_POWER ? true : onBattery;
2346            }
2347        }
2348    }
2349
2350    /**
2351     * Initialize the application bind args. These are passed to each
2352     * process when the bindApplication() IPC is sent to the process. They're
2353     * lazily setup to make sure the services are running when they're asked for.
2354     */
2355    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2356        if (mAppBindArgs == null) {
2357            mAppBindArgs = new HashMap<>();
2358
2359            // Isolated processes won't get this optimization, so that we don't
2360            // violate the rules about which services they have access to.
2361            if (!isolated) {
2362                // Setup the application init args
2363                mAppBindArgs.put("package", ServiceManager.getService("package"));
2364                mAppBindArgs.put("window", ServiceManager.getService("window"));
2365                mAppBindArgs.put(Context.ALARM_SERVICE,
2366                        ServiceManager.getService(Context.ALARM_SERVICE));
2367            }
2368        }
2369        return mAppBindArgs;
2370    }
2371
2372    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2373        if (mFocusedActivity != r) {
2374            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2375            mFocusedActivity = r;
2376            if (r.task != null && r.task.voiceInteractor != null) {
2377                startRunningVoiceLocked();
2378            } else {
2379                finishRunningVoiceLocked();
2380            }
2381            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2382            if (r != null) {
2383                mWindowManager.setFocusedApp(r.appToken, true);
2384            }
2385            applyUpdateLockStateLocked(r);
2386        }
2387        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2388                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2389    }
2390
2391    final void clearFocusedActivity(ActivityRecord r) {
2392        if (mFocusedActivity == r) {
2393            mFocusedActivity = null;
2394        }
2395    }
2396
2397    @Override
2398    public void setFocusedStack(int stackId) {
2399        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2400        synchronized (ActivityManagerService.this) {
2401            ActivityStack stack = mStackSupervisor.getStack(stackId);
2402            if (stack != null) {
2403                ActivityRecord r = stack.topRunningActivityLocked(null);
2404                if (r != null) {
2405                    setFocusedActivityLocked(r, "setFocusedStack");
2406                }
2407            }
2408        }
2409    }
2410
2411    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2412    @Override
2413    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2414        synchronized (ActivityManagerService.this) {
2415            if (listener != null) {
2416                mTaskStackListeners.register(listener);
2417            }
2418        }
2419    }
2420
2421    @Override
2422    public void notifyActivityDrawn(IBinder token) {
2423        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2424        synchronized (this) {
2425            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2426            if (r != null) {
2427                r.task.stack.notifyActivityDrawnLocked(r);
2428            }
2429        }
2430    }
2431
2432    final void applyUpdateLockStateLocked(ActivityRecord r) {
2433        // Modifications to the UpdateLock state are done on our handler, outside
2434        // the activity manager's locks.  The new state is determined based on the
2435        // state *now* of the relevant activity record.  The object is passed to
2436        // the handler solely for logging detail, not to be consulted/modified.
2437        final boolean nextState = r != null && r.immersive;
2438        mHandler.sendMessage(
2439                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2440    }
2441
2442    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2443        Message msg = Message.obtain();
2444        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2445        msg.obj = r.task.askedCompatMode ? null : r;
2446        mHandler.sendMessage(msg);
2447    }
2448
2449    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2450            String what, Object obj, ProcessRecord srcApp) {
2451        app.lastActivityTime = now;
2452
2453        if (app.activities.size() > 0) {
2454            // Don't want to touch dependent processes that are hosting activities.
2455            return index;
2456        }
2457
2458        int lrui = mLruProcesses.lastIndexOf(app);
2459        if (lrui < 0) {
2460            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2461                    + what + " " + obj + " from " + srcApp);
2462            return index;
2463        }
2464
2465        if (lrui >= index) {
2466            // Don't want to cause this to move dependent processes *back* in the
2467            // list as if they were less frequently used.
2468            return index;
2469        }
2470
2471        if (lrui >= mLruProcessActivityStart) {
2472            // Don't want to touch dependent processes that are hosting activities.
2473            return index;
2474        }
2475
2476        mLruProcesses.remove(lrui);
2477        if (index > 0) {
2478            index--;
2479        }
2480        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2481                + " in LRU list: " + app);
2482        mLruProcesses.add(index, app);
2483        return index;
2484    }
2485
2486    final void removeLruProcessLocked(ProcessRecord app) {
2487        int lrui = mLruProcesses.lastIndexOf(app);
2488        if (lrui >= 0) {
2489            if (!app.killed) {
2490                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2491                Process.killProcessQuiet(app.pid);
2492                Process.killProcessGroup(app.info.uid, app.pid);
2493            }
2494            if (lrui <= mLruProcessActivityStart) {
2495                mLruProcessActivityStart--;
2496            }
2497            if (lrui <= mLruProcessServiceStart) {
2498                mLruProcessServiceStart--;
2499            }
2500            mLruProcesses.remove(lrui);
2501        }
2502    }
2503
2504    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2505            ProcessRecord client) {
2506        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2507                || app.treatLikeActivity;
2508        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2509        if (!activityChange && hasActivity) {
2510            // The process has activities, so we are only allowing activity-based adjustments
2511            // to move it.  It should be kept in the front of the list with other
2512            // processes that have activities, and we don't want those to change their
2513            // order except due to activity operations.
2514            return;
2515        }
2516
2517        mLruSeq++;
2518        final long now = SystemClock.uptimeMillis();
2519        app.lastActivityTime = now;
2520
2521        // First a quick reject: if the app is already at the position we will
2522        // put it, then there is nothing to do.
2523        if (hasActivity) {
2524            final int N = mLruProcesses.size();
2525            if (N > 0 && mLruProcesses.get(N-1) == app) {
2526                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2527                return;
2528            }
2529        } else {
2530            if (mLruProcessServiceStart > 0
2531                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2532                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2533                return;
2534            }
2535        }
2536
2537        int lrui = mLruProcesses.lastIndexOf(app);
2538
2539        if (app.persistent && lrui >= 0) {
2540            // We don't care about the position of persistent processes, as long as
2541            // they are in the list.
2542            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2543            return;
2544        }
2545
2546        /* In progress: compute new position first, so we can avoid doing work
2547           if the process is not actually going to move.  Not yet working.
2548        int addIndex;
2549        int nextIndex;
2550        boolean inActivity = false, inService = false;
2551        if (hasActivity) {
2552            // Process has activities, put it at the very tipsy-top.
2553            addIndex = mLruProcesses.size();
2554            nextIndex = mLruProcessServiceStart;
2555            inActivity = true;
2556        } else if (hasService) {
2557            // Process has services, put it at the top of the service list.
2558            addIndex = mLruProcessActivityStart;
2559            nextIndex = mLruProcessServiceStart;
2560            inActivity = true;
2561            inService = true;
2562        } else  {
2563            // Process not otherwise of interest, it goes to the top of the non-service area.
2564            addIndex = mLruProcessServiceStart;
2565            if (client != null) {
2566                int clientIndex = mLruProcesses.lastIndexOf(client);
2567                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2568                        + app);
2569                if (clientIndex >= 0 && addIndex > clientIndex) {
2570                    addIndex = clientIndex;
2571                }
2572            }
2573            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2574        }
2575
2576        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2577                + mLruProcessActivityStart + "): " + app);
2578        */
2579
2580        if (lrui >= 0) {
2581            if (lrui < mLruProcessActivityStart) {
2582                mLruProcessActivityStart--;
2583            }
2584            if (lrui < mLruProcessServiceStart) {
2585                mLruProcessServiceStart--;
2586            }
2587            /*
2588            if (addIndex > lrui) {
2589                addIndex--;
2590            }
2591            if (nextIndex > lrui) {
2592                nextIndex--;
2593            }
2594            */
2595            mLruProcesses.remove(lrui);
2596        }
2597
2598        /*
2599        mLruProcesses.add(addIndex, app);
2600        if (inActivity) {
2601            mLruProcessActivityStart++;
2602        }
2603        if (inService) {
2604            mLruProcessActivityStart++;
2605        }
2606        */
2607
2608        int nextIndex;
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2612                // Process doesn't have activities, but has clients with
2613                // activities...  move it up, but one below the top (the top
2614                // should always have a real activity).
2615                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2616                mLruProcesses.add(N-1, app);
2617                // To keep it from spamming the LRU list (by making a bunch of clients),
2618                // we will push down any other entries owned by the app.
2619                final int uid = app.info.uid;
2620                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2621                    ProcessRecord subProc = mLruProcesses.get(i);
2622                    if (subProc.info.uid == uid) {
2623                        // We want to push this one down the list.  If the process after
2624                        // it is for the same uid, however, don't do so, because we don't
2625                        // want them internally to be re-ordered.
2626                        if (mLruProcesses.get(i-1).info.uid != uid) {
2627                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2628                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2629                            ProcessRecord tmp = mLruProcesses.get(i);
2630                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2631                            mLruProcesses.set(i-1, tmp);
2632                            i--;
2633                        }
2634                    } else {
2635                        // A gap, we can stop here.
2636                        break;
2637                    }
2638                }
2639            } else {
2640                // Process has activities, put it at the very tipsy-top.
2641                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2642                mLruProcesses.add(app);
2643            }
2644            nextIndex = mLruProcessServiceStart;
2645        } else if (hasService) {
2646            // Process has services, put it at the top of the service list.
2647            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2648            mLruProcesses.add(mLruProcessActivityStart, app);
2649            nextIndex = mLruProcessServiceStart;
2650            mLruProcessActivityStart++;
2651        } else  {
2652            // Process not otherwise of interest, it goes to the top of the non-service area.
2653            int index = mLruProcessServiceStart;
2654            if (client != null) {
2655                // If there is a client, don't allow the process to be moved up higher
2656                // in the list than that client.
2657                int clientIndex = mLruProcesses.lastIndexOf(client);
2658                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2659                        + " when updating " + app);
2660                if (clientIndex <= lrui) {
2661                    // Don't allow the client index restriction to push it down farther in the
2662                    // list than it already is.
2663                    clientIndex = lrui;
2664                }
2665                if (clientIndex >= 0 && index > clientIndex) {
2666                    index = clientIndex;
2667                }
2668            }
2669            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2670            mLruProcesses.add(index, app);
2671            nextIndex = index-1;
2672            mLruProcessActivityStart++;
2673            mLruProcessServiceStart++;
2674        }
2675
2676        // If the app is currently using a content provider or service,
2677        // bump those processes as well.
2678        for (int j=app.connections.size()-1; j>=0; j--) {
2679            ConnectionRecord cr = app.connections.valueAt(j);
2680            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2681                    && cr.binding.service.app != null
2682                    && cr.binding.service.app.lruSeq != mLruSeq
2683                    && !cr.binding.service.app.persistent) {
2684                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2685                        "service connection", cr, app);
2686            }
2687        }
2688        for (int j=app.conProviders.size()-1; j>=0; j--) {
2689            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2690            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2691                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2692                        "provider reference", cpr, app);
2693            }
2694        }
2695    }
2696
2697    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2698        if (uid == Process.SYSTEM_UID) {
2699            // The system gets to run in any process.  If there are multiple
2700            // processes with the same uid, just pick the first (this
2701            // should never happen).
2702            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2703            if (procs == null) return null;
2704            final int N = procs.size();
2705            for (int i = 0; i < N; i++) {
2706                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2707            }
2708        }
2709        ProcessRecord proc = mProcessNames.get(processName, uid);
2710        if (false && proc != null && !keepIfLarge
2711                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2712                && proc.lastCachedPss >= 4000) {
2713            // Turn this condition on to cause killing to happen regularly, for testing.
2714            if (proc.baseProcessTracker != null) {
2715                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2716            }
2717            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2718        } else if (proc != null && !keepIfLarge
2719                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2720                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2721            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2722            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2723                if (proc.baseProcessTracker != null) {
2724                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2725                }
2726                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2727            }
2728        }
2729        return proc;
2730    }
2731
2732    void ensurePackageDexOpt(String packageName) {
2733        IPackageManager pm = AppGlobals.getPackageManager();
2734        try {
2735            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2736                mDidDexOpt = true;
2737            }
2738        } catch (RemoteException e) {
2739        }
2740    }
2741
2742    boolean isNextTransitionForward() {
2743        int transit = mWindowManager.getPendingAppTransition();
2744        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2745                || transit == AppTransition.TRANSIT_TASK_OPEN
2746                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2747    }
2748
2749    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2750            String processName, String abiOverride, int uid, Runnable crashHandler) {
2751        synchronized(this) {
2752            ApplicationInfo info = new ApplicationInfo();
2753            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2754            // For isolated processes, the former contains the parent's uid and the latter the
2755            // actual uid of the isolated process.
2756            // In the special case introduced by this method (which is, starting an isolated
2757            // process directly from the SystemServer without an actual parent app process) the
2758            // closest thing to a parent's uid is SYSTEM_UID.
2759            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2760            // the |isolated| logic in the ProcessRecord constructor.
2761            info.uid = Process.SYSTEM_UID;
2762            info.processName = processName;
2763            info.className = entryPoint;
2764            info.packageName = "android";
2765            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2766                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2767                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2768                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2769                    crashHandler);
2770            return proc != null ? proc.pid : 0;
2771        }
2772    }
2773
2774    final ProcessRecord startProcessLocked(String processName,
2775            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2776            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2777            boolean isolated, boolean keepIfLarge) {
2778        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2779                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2780                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2781                null /* crashHandler */);
2782    }
2783
2784    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2785            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2786            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2787            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2788        long startTime = SystemClock.elapsedRealtime();
2789        ProcessRecord app;
2790        if (!isolated) {
2791            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2792            checkTime(startTime, "startProcess: after getProcessRecord");
2793        } else {
2794            // If this is an isolated process, it can't re-use an existing process.
2795            app = null;
2796        }
2797        // We don't have to do anything more if:
2798        // (1) There is an existing application record; and
2799        // (2) The caller doesn't think it is dead, OR there is no thread
2800        //     object attached to it so we know it couldn't have crashed; and
2801        // (3) There is a pid assigned to it, so it is either starting or
2802        //     already running.
2803        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2804                + " app=" + app + " knownToBeDead=" + knownToBeDead
2805                + " thread=" + (app != null ? app.thread : null)
2806                + " pid=" + (app != null ? app.pid : -1));
2807        if (app != null && app.pid > 0) {
2808            if (!knownToBeDead || app.thread == null) {
2809                // We already have the app running, or are waiting for it to
2810                // come up (we have a pid but not yet its thread), so keep it.
2811                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2812                // If this is a new package in the process, add the package to the list
2813                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2814                checkTime(startTime, "startProcess: done, added package to proc");
2815                return app;
2816            }
2817
2818            // An application record is attached to a previous process,
2819            // clean it up now.
2820            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2821            checkTime(startTime, "startProcess: bad proc running, killing");
2822            Process.killProcessGroup(app.info.uid, app.pid);
2823            handleAppDiedLocked(app, true, true);
2824            checkTime(startTime, "startProcess: done killing old proc");
2825        }
2826
2827        String hostingNameStr = hostingName != null
2828                ? hostingName.flattenToShortString() : null;
2829
2830        if (!isolated) {
2831            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2832                // If we are in the background, then check to see if this process
2833                // is bad.  If so, we will just silently fail.
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2836                            + "/" + info.processName);
2837                    return null;
2838                }
2839            } else {
2840                // When the user is explicitly starting a process, then clear its
2841                // crash count so that we won't make it bad until they see at
2842                // least one crash dialog again, and make the process good again
2843                // if it had been bad.
2844                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2845                        + "/" + info.processName);
2846                mProcessCrashTimes.remove(info.processName, info.uid);
2847                if (mBadProcesses.get(info.processName, info.uid) != null) {
2848                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2849                            UserHandle.getUserId(info.uid), info.uid,
2850                            info.processName);
2851                    mBadProcesses.remove(info.processName, info.uid);
2852                    if (app != null) {
2853                        app.bad = false;
2854                    }
2855                }
2856            }
2857        }
2858
2859        if (app == null) {
2860            checkTime(startTime, "startProcess: creating new process record");
2861            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2862            if (app == null) {
2863                Slog.w(TAG, "Failed making new process record for "
2864                        + processName + "/" + info.uid + " isolated=" + isolated);
2865                return null;
2866            }
2867            app.crashHandler = crashHandler;
2868            mProcessNames.put(processName, app.uid, app);
2869            if (isolated) {
2870                mIsolatedProcesses.put(app.uid, app);
2871            }
2872            checkTime(startTime, "startProcess: done creating new process record");
2873        } else {
2874            // If this is a new package in the process, add the package to the list
2875            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2876            checkTime(startTime, "startProcess: added package to existing proc");
2877        }
2878
2879        // If the system is not ready yet, then hold off on starting this
2880        // process until it is.
2881        if (!mProcessesReady
2882                && !isAllowedWhileBooting(info)
2883                && !allowWhileBooting) {
2884            if (!mProcessesOnHold.contains(app)) {
2885                mProcessesOnHold.add(app);
2886            }
2887            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2888            checkTime(startTime, "startProcess: returning with proc on hold");
2889            return app;
2890        }
2891
2892        checkTime(startTime, "startProcess: stepping in to startProcess");
2893        startProcessLocked(
2894                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2895        checkTime(startTime, "startProcess: done starting proc!");
2896        return (app.pid != 0) ? app : null;
2897    }
2898
2899    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2900        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2901    }
2902
2903    private final void startProcessLocked(ProcessRecord app,
2904            String hostingType, String hostingNameStr) {
2905        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2906                null /* entryPoint */, null /* entryPointArgs */);
2907    }
2908
2909    private final void startProcessLocked(ProcessRecord app, String hostingType,
2910            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2911        long startTime = SystemClock.elapsedRealtime();
2912        if (app.pid > 0 && app.pid != MY_PID) {
2913            checkTime(startTime, "startProcess: removing from pids map");
2914            synchronized (mPidsSelfLocked) {
2915                mPidsSelfLocked.remove(app.pid);
2916                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2917            }
2918            checkTime(startTime, "startProcess: done removing from pids map");
2919            app.setPid(0);
2920        }
2921
2922        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2923                "startProcessLocked removing on hold: " + app);
2924        mProcessesOnHold.remove(app);
2925
2926        checkTime(startTime, "startProcess: starting to update cpu stats");
2927        updateCpuStats();
2928        checkTime(startTime, "startProcess: done updating cpu stats");
2929
2930        try {
2931            int uid = app.uid;
2932
2933            int[] gids = null;
2934            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2935            if (!app.isolated) {
2936                int[] permGids = null;
2937                try {
2938                    checkTime(startTime, "startProcess: getting gids from package manager");
2939                    final PackageManager pm = mContext.getPackageManager();
2940                    permGids = pm.getPackageGids(app.info.packageName);
2941
2942                    if (Environment.isExternalStorageEmulated()) {
2943                        checkTime(startTime, "startProcess: checking external storage perm");
2944                        if (pm.checkPermission(
2945                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2946                                app.info.packageName) == PERMISSION_GRANTED) {
2947                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2948                        } else {
2949                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2950                        }
2951                    }
2952                } catch (PackageManager.NameNotFoundException e) {
2953                    Slog.w(TAG, "Unable to retrieve gids", e);
2954                }
2955
2956                /*
2957                 * Add shared application and profile GIDs so applications can share some
2958                 * resources like shared libraries and access user-wide resources
2959                 */
2960                if (permGids == null) {
2961                    gids = new int[2];
2962                } else {
2963                    gids = new int[permGids.length + 2];
2964                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2965                }
2966                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2967                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2968            }
2969            checkTime(startTime, "startProcess: building args");
2970            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2971                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2972                        && mTopComponent != null
2973                        && app.processName.equals(mTopComponent.getPackageName())) {
2974                    uid = 0;
2975                }
2976                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2977                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2978                    uid = 0;
2979                }
2980            }
2981            int debugFlags = 0;
2982            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2984                // Also turn on CheckJNI for debuggable apps. It's quite
2985                // awkward to turn on otherwise.
2986                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2987            }
2988            // Run the app in safe mode if its manifest requests so or the
2989            // system is booted in safe mode.
2990            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2991                mSafeMode == true) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2996            }
2997            String jitDebugProperty = SystemProperties.get("debug.usejit");
2998            if ("true".equals(jitDebugProperty)) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3000            } else if (!"false".equals(jitDebugProperty)) {
3001                // If we didn't force disable by setting false, defer to the dalvik vm options.
3002                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3003                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3004                }
3005            }
3006            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3007                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3008            }
3009            if ("1".equals(SystemProperties.get("debug.assert"))) {
3010                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3011            }
3012
3013            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3014            if (requiredAbi == null) {
3015                requiredAbi = Build.SUPPORTED_ABIS[0];
3016            }
3017
3018            String instructionSet = null;
3019            if (app.info.primaryCpuAbi != null) {
3020                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3021            }
3022
3023            app.gids = gids;
3024            app.requiredAbi = requiredAbi;
3025            app.instructionSet = instructionSet;
3026
3027            // Start the process.  It will either succeed and return a result containing
3028            // the PID of the new process, or else throw a RuntimeException.
3029            boolean isActivityProcess = (entryPoint == null);
3030            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3031            checkTime(startTime, "startProcess: asking zygote to start proc");
3032            Process.ProcessStartResult startResult = Process.start(entryPoint,
3033                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3034                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3035                    app.info.dataDir, entryPointArgs);
3036            checkTime(startTime, "startProcess: returned from zygote!");
3037
3038            if (app.isolated) {
3039                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3040            }
3041            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3042            checkTime(startTime, "startProcess: done updating battery stats");
3043
3044            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3045                    UserHandle.getUserId(uid), startResult.pid, uid,
3046                    app.processName, hostingType,
3047                    hostingNameStr != null ? hostingNameStr : "");
3048
3049            if (app.persistent) {
3050                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3051            }
3052
3053            checkTime(startTime, "startProcess: building log message");
3054            StringBuilder buf = mStringBuilder;
3055            buf.setLength(0);
3056            buf.append("Start proc ");
3057            buf.append(startResult.pid);
3058            buf.append(':');
3059            buf.append(app.processName);
3060            buf.append('/');
3061            UserHandle.formatUid(buf, uid);
3062            if (!isActivityProcess) {
3063                buf.append(" [");
3064                buf.append(entryPoint);
3065                buf.append("]");
3066            }
3067            buf.append(" for ");
3068            buf.append(hostingType);
3069            if (hostingNameStr != null) {
3070                buf.append(" ");
3071                buf.append(hostingNameStr);
3072            }
3073            Slog.i(TAG, buf.toString());
3074            app.setPid(startResult.pid);
3075            app.usingWrapper = startResult.usingWrapper;
3076            app.removed = false;
3077            app.killed = false;
3078            app.killedByAm = false;
3079            checkTime(startTime, "startProcess: starting to update pids map");
3080            synchronized (mPidsSelfLocked) {
3081                this.mPidsSelfLocked.put(startResult.pid, app);
3082                if (isActivityProcess) {
3083                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3084                    msg.obj = app;
3085                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3086                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3087                }
3088            }
3089            checkTime(startTime, "startProcess: done updating pids map");
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3108            }
3109            synchronized (stats) {
3110                stats.noteActivityResumedLocked(component.app.uid);
3111            }
3112        } else {
3113            if (mUsageStatsService != null) {
3114                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3115                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3116            }
3117            synchronized (stats) {
3118                stats.noteActivityPausedLocked(component.app.uid);
3119            }
3120        }
3121    }
3122
3123    Intent getHomeIntent() {
3124        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3125        intent.setComponent(mTopComponent);
3126        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3127            intent.addCategory(Intent.CATEGORY_HOME);
3128        }
3129        return intent;
3130    }
3131
3132    boolean startHomeActivityLocked(int userId, String reason) {
3133        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3134                && mTopAction == null) {
3135            // We are running in factory test mode, but unable to find
3136            // the factory test app, so just sit around displaying the
3137            // error message and don't try to start anything.
3138            return false;
3139        }
3140        Intent intent = getHomeIntent();
3141        ActivityInfo aInfo =
3142            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3143        if (aInfo != null) {
3144            intent.setComponent(new ComponentName(
3145                    aInfo.applicationInfo.packageName, aInfo.name));
3146            // Don't do this if the home app is currently being
3147            // instrumented.
3148            aInfo = new ActivityInfo(aInfo);
3149            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3150            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3151                    aInfo.applicationInfo.uid, true);
3152            if (app == null || app.instrumentationClass == null) {
3153                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3154                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3155            }
3156        }
3157
3158        return true;
3159    }
3160
3161    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3162        ActivityInfo ai = null;
3163        ComponentName comp = intent.getComponent();
3164        try {
3165            if (comp != null) {
3166                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3167            } else {
3168                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3169                        intent,
3170                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3171                            flags, userId);
3172
3173                if (info != null) {
3174                    ai = info.activityInfo;
3175                }
3176            }
3177        } catch (RemoteException e) {
3178            // ignore
3179        }
3180
3181        return ai;
3182    }
3183
3184    /**
3185     * Starts the "new version setup screen" if appropriate.
3186     */
3187    void startSetupActivityLocked() {
3188        // Only do this once per boot.
3189        if (mCheckedForSetup) {
3190            return;
3191        }
3192
3193        // We will show this screen if the current one is a different
3194        // version than the last one shown, and we are not running in
3195        // low-level factory test mode.
3196        final ContentResolver resolver = mContext.getContentResolver();
3197        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3198                Settings.Global.getInt(resolver,
3199                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3200            mCheckedForSetup = true;
3201
3202            // See if we should be showing the platform update setup UI.
3203            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3204            List<ResolveInfo> ris = mContext.getPackageManager()
3205                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3206
3207            // We don't allow third party apps to replace this.
3208            ResolveInfo ri = null;
3209            for (int i=0; ris != null && i<ris.size(); i++) {
3210                if ((ris.get(i).activityInfo.applicationInfo.flags
3211                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3212                    ri = ris.get(i);
3213                    break;
3214                }
3215            }
3216
3217            if (ri != null) {
3218                String vers = ri.activityInfo.metaData != null
3219                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3220                        : null;
3221                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3222                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3223                            Intent.METADATA_SETUP_VERSION);
3224                }
3225                String lastVers = Settings.Secure.getString(
3226                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3227                if (vers != null && !vers.equals(lastVers)) {
3228                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3229                    intent.setComponent(new ComponentName(
3230                            ri.activityInfo.packageName, ri.activityInfo.name));
3231                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3232                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3233                            null);
3234                }
3235            }
3236        }
3237    }
3238
3239    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3240        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3241    }
3242
3243    void enforceNotIsolatedCaller(String caller) {
3244        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3245            throw new SecurityException("Isolated process not allowed to call " + caller);
3246        }
3247    }
3248
3249    void enforceShellRestriction(String restriction, int userHandle) {
3250        if (Binder.getCallingUid() == Process.SHELL_UID) {
3251            if (userHandle < 0
3252                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3253                throw new SecurityException("Shell does not have permission to access user "
3254                        + userHandle);
3255            }
3256        }
3257    }
3258
3259    @Override
3260    public int getFrontActivityScreenCompatMode() {
3261        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3264        }
3265    }
3266
3267    @Override
3268    public void setFrontActivityScreenCompatMode(int mode) {
3269        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3270                "setFrontActivityScreenCompatMode");
3271        synchronized (this) {
3272            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3273        }
3274    }
3275
3276    @Override
3277    public int getPackageScreenCompatMode(String packageName) {
3278        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3279        synchronized (this) {
3280            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3281        }
3282    }
3283
3284    @Override
3285    public void setPackageScreenCompatMode(String packageName, int mode) {
3286        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3287                "setPackageScreenCompatMode");
3288        synchronized (this) {
3289            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3290        }
3291    }
3292
3293    @Override
3294    public boolean getPackageAskScreenCompat(String packageName) {
3295        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3296        synchronized (this) {
3297            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3298        }
3299    }
3300
3301    @Override
3302    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3303        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3304                "setPackageAskScreenCompat");
3305        synchronized (this) {
3306            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3307        }
3308    }
3309
3310    private void dispatchProcessesChanged() {
3311        int N;
3312        synchronized (this) {
3313            N = mPendingProcessChanges.size();
3314            if (mActiveProcessChanges.length < N) {
3315                mActiveProcessChanges = new ProcessChangeItem[N];
3316            }
3317            mPendingProcessChanges.toArray(mActiveProcessChanges);
3318            mAvailProcessChanges.addAll(mPendingProcessChanges);
3319            mPendingProcessChanges.clear();
3320            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3321        }
3322
3323        int i = mProcessObservers.beginBroadcast();
3324        while (i > 0) {
3325            i--;
3326            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3327            if (observer != null) {
3328                try {
3329                    for (int j=0; j<N; j++) {
3330                        ProcessChangeItem item = mActiveProcessChanges[j];
3331                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3332                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3333                                    + item.pid + " uid=" + item.uid + ": "
3334                                    + item.foregroundActivities);
3335                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3336                                    item.foregroundActivities);
3337                        }
3338                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3339                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3340                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3341                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3342                        }
3343                    }
3344                } catch (RemoteException e) {
3345                }
3346            }
3347        }
3348        mProcessObservers.finishBroadcast();
3349    }
3350
3351    private void dispatchProcessDied(int pid, int uid) {
3352        int i = mProcessObservers.beginBroadcast();
3353        while (i > 0) {
3354            i--;
3355            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3356            if (observer != null) {
3357                try {
3358                    observer.onProcessDied(pid, uid);
3359                } catch (RemoteException e) {
3360                }
3361            }
3362        }
3363        mProcessObservers.finishBroadcast();
3364    }
3365
3366    @Override
3367    public final int startActivity(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3369            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3370        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3371            resultWho, requestCode, startFlags, profilerInfo, options,
3372            UserHandle.getCallingUserId());
3373    }
3374
3375    @Override
3376    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3377            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3378            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3379        enforceNotIsolatedCaller("startActivity");
3380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3381                false, ALLOW_FULL_ONLY, "startActivity", null);
3382        // TODO: Switch to user app stacks here.
3383        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3384                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3385                profilerInfo, null, null, options, userId, null, null);
3386    }
3387
3388    @Override
3389    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3390            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3391            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3392
3393        // This is very dangerous -- it allows you to perform a start activity (including
3394        // permission grants) as any app that may launch one of your own activities.  So
3395        // we will only allow this to be done from activities that are part of the core framework,
3396        // and then only when they are running as the system.
3397        final ActivityRecord sourceRecord;
3398        final int targetUid;
3399        final String targetPackage;
3400        synchronized (this) {
3401            if (resultTo == null) {
3402                throw new SecurityException("Must be called from an activity");
3403            }
3404            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3405            if (sourceRecord == null) {
3406                throw new SecurityException("Called with bad activity token: " + resultTo);
3407            }
3408            if (!sourceRecord.info.packageName.equals("android")) {
3409                throw new SecurityException(
3410                        "Must be called from an activity that is declared in the android package");
3411            }
3412            if (sourceRecord.app == null) {
3413                throw new SecurityException("Called without a process attached to activity");
3414            }
3415            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3416                // This is still okay, as long as this activity is running under the
3417                // uid of the original calling activity.
3418                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3419                    throw new SecurityException(
3420                            "Calling activity in uid " + sourceRecord.app.uid
3421                                    + " must be system uid or original calling uid "
3422                                    + sourceRecord.launchedFromUid);
3423                }
3424            }
3425            targetUid = sourceRecord.launchedFromUid;
3426            targetPackage = sourceRecord.launchedFromPackage;
3427        }
3428
3429        if (userId == UserHandle.USER_NULL) {
3430            userId = UserHandle.getUserId(sourceRecord.app.uid);
3431        }
3432
3433        // TODO: Switch to user app stacks here.
3434        try {
3435            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3436                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3437                    null, null, options, userId, null, null);
3438            return ret;
3439        } catch (SecurityException e) {
3440            // XXX need to figure out how to propagate to original app.
3441            // A SecurityException here is generally actually a fault of the original
3442            // calling activity (such as a fairly granting permissions), so propagate it
3443            // back to them.
3444            /*
3445            StringBuilder msg = new StringBuilder();
3446            msg.append("While launching");
3447            msg.append(intent.toString());
3448            msg.append(": ");
3449            msg.append(e.getMessage());
3450            */
3451            throw e;
3452        }
3453    }
3454
3455    @Override
3456    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3458            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3459        enforceNotIsolatedCaller("startActivityAndWait");
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3462        WaitResult res = new WaitResult();
3463        // TODO: Switch to user app stacks here.
3464        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3465                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3466                options, userId, null, null);
3467        return res;
3468    }
3469
3470    @Override
3471    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3472            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3473            int startFlags, Configuration config, Bundle options, int userId) {
3474        enforceNotIsolatedCaller("startActivityWithConfig");
3475        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3476                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3477        // TODO: Switch to user app stacks here.
3478        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3479                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3480                null, null, config, options, userId, null, null);
3481        return ret;
3482    }
3483
3484    @Override
3485    public int startActivityIntentSender(IApplicationThread caller,
3486            IntentSender intent, Intent fillInIntent, String resolvedType,
3487            IBinder resultTo, String resultWho, int requestCode,
3488            int flagsMask, int flagsValues, Bundle options) {
3489        enforceNotIsolatedCaller("startActivityIntentSender");
3490        // Refuse possible leaked file descriptors
3491        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3492            throw new IllegalArgumentException("File descriptors passed in Intent");
3493        }
3494
3495        IIntentSender sender = intent.getTarget();
3496        if (!(sender instanceof PendingIntentRecord)) {
3497            throw new IllegalArgumentException("Bad PendingIntent object");
3498        }
3499
3500        PendingIntentRecord pir = (PendingIntentRecord)sender;
3501
3502        synchronized (this) {
3503            // If this is coming from the currently resumed activity, it is
3504            // effectively saying that app switches are allowed at this point.
3505            final ActivityStack stack = getFocusedStack();
3506            if (stack.mResumedActivity != null &&
3507                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3508                mAppSwitchesAllowedTime = 0;
3509            }
3510        }
3511        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3512                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3513        return ret;
3514    }
3515
3516    @Override
3517    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3518            Intent intent, String resolvedType, IVoiceInteractionSession session,
3519            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3520            Bundle options, int userId) {
3521        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3522                != PackageManager.PERMISSION_GRANTED) {
3523            String msg = "Permission Denial: startVoiceActivity() from pid="
3524                    + Binder.getCallingPid()
3525                    + ", uid=" + Binder.getCallingUid()
3526                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3527            Slog.w(TAG, msg);
3528            throw new SecurityException(msg);
3529        }
3530        if (session == null || interactor == null) {
3531            throw new NullPointerException("null session or interactor");
3532        }
3533        userId = handleIncomingUser(callingPid, callingUid, userId,
3534                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3535        // TODO: Switch to user app stacks here.
3536        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3537                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3538                null, options, userId, null, null);
3539    }
3540
3541    @Override
3542    public boolean startNextMatchingActivity(IBinder callingActivity,
3543            Intent intent, Bundle options) {
3544        // Refuse possible leaked file descriptors
3545        if (intent != null && intent.hasFileDescriptors() == true) {
3546            throw new IllegalArgumentException("File descriptors passed in Intent");
3547        }
3548
3549        synchronized (this) {
3550            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3551            if (r == null) {
3552                ActivityOptions.abort(options);
3553                return false;
3554            }
3555            if (r.app == null || r.app.thread == null) {
3556                // The caller is not running...  d'oh!
3557                ActivityOptions.abort(options);
3558                return false;
3559            }
3560            intent = new Intent(intent);
3561            // The caller is not allowed to change the data.
3562            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3563            // And we are resetting to find the next component...
3564            intent.setComponent(null);
3565
3566            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3567
3568            ActivityInfo aInfo = null;
3569            try {
3570                List<ResolveInfo> resolves =
3571                    AppGlobals.getPackageManager().queryIntentActivities(
3572                            intent, r.resolvedType,
3573                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3574                            UserHandle.getCallingUserId());
3575
3576                // Look for the original activity in the list...
3577                final int N = resolves != null ? resolves.size() : 0;
3578                for (int i=0; i<N; i++) {
3579                    ResolveInfo rInfo = resolves.get(i);
3580                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3581                            && rInfo.activityInfo.name.equals(r.info.name)) {
3582                        // We found the current one...  the next matching is
3583                        // after it.
3584                        i++;
3585                        if (i<N) {
3586                            aInfo = resolves.get(i).activityInfo;
3587                        }
3588                        if (debug) {
3589                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3590                                    + "/" + r.info.name);
3591                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3592                                    + "/" + aInfo.name);
3593                        }
3594                        break;
3595                    }
3596                }
3597            } catch (RemoteException e) {
3598            }
3599
3600            if (aInfo == null) {
3601                // Nobody who is next!
3602                ActivityOptions.abort(options);
3603                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3604                return false;
3605            }
3606
3607            intent.setComponent(new ComponentName(
3608                    aInfo.applicationInfo.packageName, aInfo.name));
3609            intent.setFlags(intent.getFlags()&~(
3610                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3611                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3612                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3613                    Intent.FLAG_ACTIVITY_NEW_TASK));
3614
3615            // Okay now we need to start the new activity, replacing the
3616            // currently running activity.  This is a little tricky because
3617            // we want to start the new one as if the current one is finished,
3618            // but not finish the current one first so that there is no flicker.
3619            // And thus...
3620            final boolean wasFinishing = r.finishing;
3621            r.finishing = true;
3622
3623            // Propagate reply information over to the new activity.
3624            final ActivityRecord resultTo = r.resultTo;
3625            final String resultWho = r.resultWho;
3626            final int requestCode = r.requestCode;
3627            r.resultTo = null;
3628            if (resultTo != null) {
3629                resultTo.removeResultsLocked(r, resultWho, requestCode);
3630            }
3631
3632            final long origId = Binder.clearCallingIdentity();
3633            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3634                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3635                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3636                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3637            Binder.restoreCallingIdentity(origId);
3638
3639            r.finishing = wasFinishing;
3640            if (res != ActivityManager.START_SUCCESS) {
3641                return false;
3642            }
3643            return true;
3644        }
3645    }
3646
3647    @Override
3648    public final int startActivityFromRecents(int taskId, Bundle options) {
3649        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3650            String msg = "Permission Denial: startActivityFromRecents called without " +
3651                    START_TASKS_FROM_RECENTS;
3652            Slog.w(TAG, msg);
3653            throw new SecurityException(msg);
3654        }
3655        return startActivityFromRecentsInner(taskId, options);
3656    }
3657
3658    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3659        final TaskRecord task;
3660        final int callingUid;
3661        final String callingPackage;
3662        final Intent intent;
3663        final int userId;
3664        synchronized (this) {
3665            task = recentTaskForIdLocked(taskId);
3666            if (task == null) {
3667                throw new IllegalArgumentException("Task " + taskId + " not found.");
3668            }
3669            if (task.getRootActivity() != null) {
3670                moveTaskToFrontLocked(task.taskId, 0, null);
3671                return ActivityManager.START_TASK_TO_FRONT;
3672            }
3673            callingUid = task.mCallingUid;
3674            callingPackage = task.mCallingPackage;
3675            intent = task.intent;
3676            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3677            userId = task.userId;
3678        }
3679        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3680                options, userId, null, task);
3681    }
3682
3683    final int startActivityInPackage(int uid, String callingPackage,
3684            Intent intent, String resolvedType, IBinder resultTo,
3685            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3686            IActivityContainer container, TaskRecord inTask) {
3687
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3690
3691        // TODO: Switch to user app stacks here.
3692        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3693                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3694                null, null, null, options, userId, container, inTask);
3695        return ret;
3696    }
3697
3698    @Override
3699    public final int startActivities(IApplicationThread caller, String callingPackage,
3700            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3701            int userId) {
3702        enforceNotIsolatedCaller("startActivities");
3703        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3704                false, ALLOW_FULL_ONLY, "startActivity", null);
3705        // TODO: Switch to user app stacks here.
3706        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3707                resolvedTypes, resultTo, options, userId);
3708        return ret;
3709    }
3710
3711    final int startActivitiesInPackage(int uid, String callingPackage,
3712            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3713            Bundle options, int userId) {
3714
3715        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3716                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3717        // TODO: Switch to user app stacks here.
3718        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3719                resultTo, options, userId);
3720        return ret;
3721    }
3722
3723    //explicitly remove thd old information in mRecentTasks when removing existing user.
3724    private void removeRecentTasksForUserLocked(int userId) {
3725        if(userId <= 0) {
3726            Slog.i(TAG, "Can't remove recent task on user " + userId);
3727            return;
3728        }
3729
3730        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3731            TaskRecord tr = mRecentTasks.get(i);
3732            if (tr.userId == userId) {
3733                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3734                        + " when finishing user" + userId);
3735                mRecentTasks.remove(i);
3736                tr.removedFromRecents();
3737            }
3738        }
3739
3740        // Remove tasks from persistent storage.
3741        notifyTaskPersisterLocked(null, true);
3742    }
3743
3744    // Sort by taskId
3745    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3746        @Override
3747        public int compare(TaskRecord lhs, TaskRecord rhs) {
3748            return rhs.taskId - lhs.taskId;
3749        }
3750    };
3751
3752    // Extract the affiliates of the chain containing mRecentTasks[start].
3753    private int processNextAffiliateChainLocked(int start) {
3754        final TaskRecord startTask = mRecentTasks.get(start);
3755        final int affiliateId = startTask.mAffiliatedTaskId;
3756
3757        // Quick identification of isolated tasks. I.e. those not launched behind.
3758        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3759                startTask.mNextAffiliate == null) {
3760            // There is still a slim chance that there are other tasks that point to this task
3761            // and that the chain is so messed up that this task no longer points to them but
3762            // the gain of this optimization outweighs the risk.
3763            startTask.inRecents = true;
3764            return start + 1;
3765        }
3766
3767        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3768        mTmpRecents.clear();
3769        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3770            final TaskRecord task = mRecentTasks.get(i);
3771            if (task.mAffiliatedTaskId == affiliateId) {
3772                mRecentTasks.remove(i);
3773                mTmpRecents.add(task);
3774            }
3775        }
3776
3777        // Sort them all by taskId. That is the order they were create in and that order will
3778        // always be correct.
3779        Collections.sort(mTmpRecents, mTaskRecordComparator);
3780
3781        // Go through and fix up the linked list.
3782        // The first one is the end of the chain and has no next.
3783        final TaskRecord first = mTmpRecents.get(0);
3784        first.inRecents = true;
3785        if (first.mNextAffiliate != null) {
3786            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3787            first.setNextAffiliate(null);
3788            notifyTaskPersisterLocked(first, false);
3789        }
3790        // Everything in the middle is doubly linked from next to prev.
3791        final int tmpSize = mTmpRecents.size();
3792        for (int i = 0; i < tmpSize - 1; ++i) {
3793            final TaskRecord next = mTmpRecents.get(i);
3794            final TaskRecord prev = mTmpRecents.get(i + 1);
3795            if (next.mPrevAffiliate != prev) {
3796                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3797                        " setting prev=" + prev);
3798                next.setPrevAffiliate(prev);
3799                notifyTaskPersisterLocked(next, false);
3800            }
3801            if (prev.mNextAffiliate != next) {
3802                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3803                        " setting next=" + next);
3804                prev.setNextAffiliate(next);
3805                notifyTaskPersisterLocked(prev, false);
3806            }
3807            prev.inRecents = true;
3808        }
3809        // The last one is the beginning of the list and has no prev.
3810        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3811        if (last.mPrevAffiliate != null) {
3812            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3813            last.setPrevAffiliate(null);
3814            notifyTaskPersisterLocked(last, false);
3815        }
3816
3817        // Insert the group back into mRecentTasks at start.
3818        mRecentTasks.addAll(start, mTmpRecents);
3819
3820        // Let the caller know where we left off.
3821        return start + tmpSize;
3822    }
3823
3824    /**
3825     * Update the recent tasks lists: make sure tasks should still be here (their
3826     * applications / activities still exist), update their availability, fixup ordering
3827     * of affiliations.
3828     */
3829    void cleanupRecentTasksLocked(int userId) {
3830        if (mRecentTasks == null) {
3831            // Happens when called from the packagemanager broadcast before boot.
3832            return;
3833        }
3834
3835        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3836        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3837        final IPackageManager pm = AppGlobals.getPackageManager();
3838        final ActivityInfo dummyAct = new ActivityInfo();
3839        final ApplicationInfo dummyApp = new ApplicationInfo();
3840
3841        int N = mRecentTasks.size();
3842
3843        int[] users = userId == UserHandle.USER_ALL
3844                ? getUsersLocked() : new int[] { userId };
3845        for (int user : users) {
3846            for (int i = 0; i < N; i++) {
3847                TaskRecord task = mRecentTasks.get(i);
3848                if (task.userId != user) {
3849                    // Only look at tasks for the user ID of interest.
3850                    continue;
3851                }
3852                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3853                    // This situation is broken, and we should just get rid of it now.
3854                    mRecentTasks.remove(i);
3855                    task.removedFromRecents();
3856                    i--;
3857                    N--;
3858                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3859                    continue;
3860                }
3861                // Check whether this activity is currently available.
3862                if (task.realActivity != null) {
3863                    ActivityInfo ai = availActCache.get(task.realActivity);
3864                    if (ai == null) {
3865                        try {
3866                            ai = pm.getActivityInfo(task.realActivity,
3867                                    PackageManager.GET_UNINSTALLED_PACKAGES
3868                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3869                        } catch (RemoteException e) {
3870                            // Will never happen.
3871                            continue;
3872                        }
3873                        if (ai == null) {
3874                            ai = dummyAct;
3875                        }
3876                        availActCache.put(task.realActivity, ai);
3877                    }
3878                    if (ai == dummyAct) {
3879                        // This could be either because the activity no longer exists, or the
3880                        // app is temporarily gone.  For the former we want to remove the recents
3881                        // entry; for the latter we want to mark it as unavailable.
3882                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3883                        if (app == null) {
3884                            try {
3885                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3886                                        PackageManager.GET_UNINSTALLED_PACKAGES
3887                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3888                            } catch (RemoteException e) {
3889                                // Will never happen.
3890                                continue;
3891                            }
3892                            if (app == null) {
3893                                app = dummyApp;
3894                            }
3895                            availAppCache.put(task.realActivity.getPackageName(), app);
3896                        }
3897                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3898                            // Doesn't exist any more!  Good-bye.
3899                            mRecentTasks.remove(i);
3900                            task.removedFromRecents();
3901                            i--;
3902                            N--;
3903                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3904                            continue;
3905                        } else {
3906                            // Otherwise just not available for now.
3907                            if (task.isAvailable) {
3908                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3909                                        + task);
3910                            }
3911                            task.isAvailable = false;
3912                        }
3913                    } else {
3914                        if (!ai.enabled || !ai.applicationInfo.enabled
3915                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3916                            if (task.isAvailable) {
3917                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3918                                        + task + " (enabled=" + ai.enabled + "/"
3919                                        + ai.applicationInfo.enabled +  " flags="
3920                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3921                            }
3922                            task.isAvailable = false;
3923                        } else {
3924                            if (!task.isAvailable) {
3925                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3926                                        + task);
3927                            }
3928                            task.isAvailable = true;
3929                        }
3930                    }
3931                }
3932            }
3933        }
3934
3935        // Verify the affiliate chain for each task.
3936        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3937        }
3938
3939        mTmpRecents.clear();
3940        // mRecentTasks is now in sorted, affiliated order.
3941    }
3942
3943    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3944        int N = mRecentTasks.size();
3945        TaskRecord top = task;
3946        int topIndex = taskIndex;
3947        while (top.mNextAffiliate != null && topIndex > 0) {
3948            top = top.mNextAffiliate;
3949            topIndex--;
3950        }
3951        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3952                + topIndex + " from intial " + taskIndex);
3953        // Find the end of the chain, doing a sanity check along the way.
3954        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3955        int endIndex = topIndex;
3956        TaskRecord prev = top;
3957        while (endIndex < N) {
3958            TaskRecord cur = mRecentTasks.get(endIndex);
3959            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3960                    + endIndex + " " + cur);
3961            if (cur == top) {
3962                // Verify start of the chain.
3963                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3964                    Slog.wtf(TAG, "Bad chain @" + endIndex
3965                            + ": first task has next affiliate: " + prev);
3966                    sane = false;
3967                    break;
3968                }
3969            } else {
3970                // Verify middle of the chain's next points back to the one before.
3971                if (cur.mNextAffiliate != prev
3972                        || cur.mNextAffiliateTaskId != prev.taskId) {
3973                    Slog.wtf(TAG, "Bad chain @" + endIndex
3974                            + ": middle task " + cur + " @" + endIndex
3975                            + " has bad next affiliate "
3976                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3977                            + ", expected " + prev);
3978                    sane = false;
3979                    break;
3980                }
3981            }
3982            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3983                // Chain ends here.
3984                if (cur.mPrevAffiliate != null) {
3985                    Slog.wtf(TAG, "Bad chain @" + endIndex
3986                            + ": last task " + cur + " has previous affiliate "
3987                            + cur.mPrevAffiliate);
3988                    sane = false;
3989                }
3990                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3991                break;
3992            } else {
3993                // Verify middle of the chain's prev points to a valid item.
3994                if (cur.mPrevAffiliate == null) {
3995                    Slog.wtf(TAG, "Bad chain @" + endIndex
3996                            + ": task " + cur + " has previous affiliate "
3997                            + cur.mPrevAffiliate + " but should be id "
3998                            + cur.mPrevAffiliate);
3999                    sane = false;
4000                    break;
4001                }
4002            }
4003            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4004                Slog.wtf(TAG, "Bad chain @" + endIndex
4005                        + ": task " + cur + " has affiliated id "
4006                        + cur.mAffiliatedTaskId + " but should be "
4007                        + task.mAffiliatedTaskId);
4008                sane = false;
4009                break;
4010            }
4011            prev = cur;
4012            endIndex++;
4013            if (endIndex >= N) {
4014                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4015                        + ": last task " + prev);
4016                sane = false;
4017                break;
4018            }
4019        }
4020        if (sane) {
4021            if (endIndex < taskIndex) {
4022                Slog.wtf(TAG, "Bad chain @" + endIndex
4023                        + ": did not extend to task " + task + " @" + taskIndex);
4024                sane = false;
4025            }
4026        }
4027        if (sane) {
4028            // All looks good, we can just move all of the affiliated tasks
4029            // to the top.
4030            for (int i=topIndex; i<=endIndex; i++) {
4031                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4032                        + " from " + i + " to " + (i-topIndex));
4033                TaskRecord cur = mRecentTasks.remove(i);
4034                mRecentTasks.add(i-topIndex, cur);
4035            }
4036            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4037                    + " to " + endIndex);
4038            return true;
4039        }
4040
4041        // Whoops, couldn't do it.
4042        return false;
4043    }
4044
4045    final void addRecentTaskLocked(TaskRecord task) {
4046        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4047                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4048                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4049
4050        int N = mRecentTasks.size();
4051        // Quick case: check if the top-most recent task is the same.
4052        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4053            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4054            return;
4055        }
4056        // Another quick case: check if this is part of a set of affiliated
4057        // tasks that are at the top.
4058        if (isAffiliated && N > 0 && task.inRecents
4059                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4060            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4061                    + " at top when adding " + task);
4062            return;
4063        }
4064        // Another quick case: never add voice sessions.
4065        if (task.voiceSession != null) {
4066            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4067            return;
4068        }
4069
4070        boolean needAffiliationFix = false;
4071
4072        // Slightly less quick case: the task is already in recents, so all we need
4073        // to do is move it.
4074        if (task.inRecents) {
4075            int taskIndex = mRecentTasks.indexOf(task);
4076            if (taskIndex >= 0) {
4077                if (!isAffiliated) {
4078                    // Simple case: this is not an affiliated task, so we just move it to the front.
4079                    mRecentTasks.remove(taskIndex);
4080                    mRecentTasks.add(0, task);
4081                    notifyTaskPersisterLocked(task, false);
4082                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4083                            + " from " + taskIndex);
4084                    return;
4085                } else {
4086                    // More complicated: need to keep all affiliated tasks together.
4087                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4088                        // All went well.
4089                        return;
4090                    }
4091
4092                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4093                    // everything and then go through our general path of adding a new task.
4094                    needAffiliationFix = true;
4095                }
4096            } else {
4097                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4098                needAffiliationFix = true;
4099            }
4100        }
4101
4102        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4103        trimRecentsForTaskLocked(task, true);
4104
4105        N = mRecentTasks.size();
4106        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4107            final TaskRecord tr = mRecentTasks.remove(N - 1);
4108            tr.removedFromRecents();
4109            N--;
4110        }
4111        task.inRecents = true;
4112        if (!isAffiliated || needAffiliationFix) {
4113            // If this is a simple non-affiliated task, or we had some failure trying to
4114            // handle it as part of an affilated task, then just place it at the top.
4115            mRecentTasks.add(0, task);
4116        } else if (isAffiliated) {
4117            // If this is a new affiliated task, then move all of the affiliated tasks
4118            // to the front and insert this new one.
4119            TaskRecord other = task.mNextAffiliate;
4120            if (other == null) {
4121                other = task.mPrevAffiliate;
4122            }
4123            if (other != null) {
4124                int otherIndex = mRecentTasks.indexOf(other);
4125                if (otherIndex >= 0) {
4126                    // Insert new task at appropriate location.
4127                    int taskIndex;
4128                    if (other == task.mNextAffiliate) {
4129                        // We found the index of our next affiliation, which is who is
4130                        // before us in the list, so add after that point.
4131                        taskIndex = otherIndex+1;
4132                    } else {
4133                        // We found the index of our previous affiliation, which is who is
4134                        // after us in the list, so add at their position.
4135                        taskIndex = otherIndex;
4136                    }
4137                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4138                            + taskIndex + ": " + task);
4139                    mRecentTasks.add(taskIndex, task);
4140
4141                    // Now move everything to the front.
4142                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4143                        // All went well.
4144                        return;
4145                    }
4146
4147                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4148                    // everything and then go through our general path of adding a new task.
4149                    needAffiliationFix = true;
4150                } else {
4151                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4152                            + other);
4153                    needAffiliationFix = true;
4154                }
4155            } else {
4156                if (DEBUG_RECENTS) Slog.d(TAG,
4157                        "addRecent: adding affiliated task without next/prev:" + task);
4158                needAffiliationFix = true;
4159            }
4160        }
4161        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4162
4163        if (needAffiliationFix) {
4164            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4165            cleanupRecentTasksLocked(task.userId);
4166        }
4167    }
4168
4169    /**
4170     * If needed, remove oldest existing entries in recents that are for the same kind
4171     * of task as the given one.
4172     */
4173    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4174        int N = mRecentTasks.size();
4175        final Intent intent = task.intent;
4176        final boolean document = intent != null && intent.isDocument();
4177
4178        int maxRecents = task.maxRecents - 1;
4179        for (int i=0; i<N; i++) {
4180            final TaskRecord tr = mRecentTasks.get(i);
4181            if (task != tr) {
4182                if (task.userId != tr.userId) {
4183                    continue;
4184                }
4185                if (i > MAX_RECENT_BITMAPS) {
4186                    tr.freeLastThumbnail();
4187                }
4188                final Intent trIntent = tr.intent;
4189                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4190                    (intent == null || !intent.filterEquals(trIntent))) {
4191                    continue;
4192                }
4193                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4194                if (document && trIsDocument) {
4195                    // These are the same document activity (not necessarily the same doc).
4196                    if (maxRecents > 0) {
4197                        --maxRecents;
4198                        continue;
4199                    }
4200                    // Hit the maximum number of documents for this task. Fall through
4201                    // and remove this document from recents.
4202                } else if (document || trIsDocument) {
4203                    // Only one of these is a document. Not the droid we're looking for.
4204                    continue;
4205                }
4206            }
4207
4208            if (!doTrim) {
4209                // If the caller is not actually asking for a trim, just tell them we reached
4210                // a point where the trim would happen.
4211                return i;
4212            }
4213
4214            // Either task and tr are the same or, their affinities match or their intents match
4215            // and neither of them is a document, or they are documents using the same activity
4216            // and their maxRecents has been reached.
4217            tr.disposeThumbnail();
4218            mRecentTasks.remove(i);
4219            if (task != tr) {
4220                tr.removedFromRecents();
4221            }
4222            i--;
4223            N--;
4224            if (task.intent == null) {
4225                // If the new recent task we are adding is not fully
4226                // specified, then replace it with the existing recent task.
4227                task = tr;
4228            }
4229            notifyTaskPersisterLocked(tr, false);
4230        }
4231
4232        return -1;
4233    }
4234
4235    @Override
4236    public void reportActivityFullyDrawn(IBinder token) {
4237        synchronized (this) {
4238            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4239            if (r == null) {
4240                return;
4241            }
4242            r.reportFullyDrawnLocked();
4243        }
4244    }
4245
4246    @Override
4247    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4248        synchronized (this) {
4249            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4250            if (r == null) {
4251                return;
4252            }
4253            final long origId = Binder.clearCallingIdentity();
4254            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4255            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4256                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4257            if (config != null) {
4258                r.frozenBeforeDestroy = true;
4259                if (!updateConfigurationLocked(config, r, false, false)) {
4260                    mStackSupervisor.resumeTopActivitiesLocked();
4261                }
4262            }
4263            Binder.restoreCallingIdentity(origId);
4264        }
4265    }
4266
4267    @Override
4268    public int getRequestedOrientation(IBinder token) {
4269        synchronized (this) {
4270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4271            if (r == null) {
4272                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4273            }
4274            return mWindowManager.getAppOrientation(r.appToken);
4275        }
4276    }
4277
4278    /**
4279     * This is the internal entry point for handling Activity.finish().
4280     *
4281     * @param token The Binder token referencing the Activity we want to finish.
4282     * @param resultCode Result code, if any, from this Activity.
4283     * @param resultData Result data (Intent), if any, from this Activity.
4284     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4285     *            the root Activity in the task.
4286     *
4287     * @return Returns true if the activity successfully finished, or false if it is still running.
4288     */
4289    @Override
4290    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4291            boolean finishTask) {
4292        // Refuse possible leaked file descriptors
4293        if (resultData != null && resultData.hasFileDescriptors() == true) {
4294            throw new IllegalArgumentException("File descriptors passed in Intent");
4295        }
4296
4297        synchronized(this) {
4298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4299            if (r == null) {
4300                return true;
4301            }
4302            // Keep track of the root activity of the task before we finish it
4303            TaskRecord tr = r.task;
4304            ActivityRecord rootR = tr.getRootActivity();
4305            if (rootR == null) {
4306                Slog.w(TAG, "Finishing task with all activities already finished");
4307            }
4308            // Do not allow task to finish in Lock Task mode.
4309            if (tr == mStackSupervisor.mLockTaskModeTask) {
4310                if (rootR == r) {
4311                    Slog.i(TAG, "Not finishing task in lock task mode");
4312                    mStackSupervisor.showLockTaskToast();
4313                    return false;
4314                }
4315            }
4316            if (mController != null) {
4317                // Find the first activity that is not finishing.
4318                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4319                if (next != null) {
4320                    // ask watcher if this is allowed
4321                    boolean resumeOK = true;
4322                    try {
4323                        resumeOK = mController.activityResuming(next.packageName);
4324                    } catch (RemoteException e) {
4325                        mController = null;
4326                        Watchdog.getInstance().setActivityController(null);
4327                    }
4328
4329                    if (!resumeOK) {
4330                        Slog.i(TAG, "Not finishing activity because controller resumed");
4331                        return false;
4332                    }
4333                }
4334            }
4335            final long origId = Binder.clearCallingIdentity();
4336            try {
4337                boolean res;
4338                if (finishTask && r == rootR) {
4339                    // If requested, remove the task that is associated to this activity only if it
4340                    // was the root activity in the task. The result code and data is ignored
4341                    // because we don't support returning them across task boundaries.
4342                    res = removeTaskByIdLocked(tr.taskId, false);
4343                    if (!res) {
4344                        Slog.i(TAG, "Removing task failed to finish activity");
4345                    }
4346                } else {
4347                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4348                            resultData, "app-request", true);
4349                    if (!res) {
4350                        Slog.i(TAG, "Failed to finish by app-request");
4351                    }
4352                }
4353                return res;
4354            } finally {
4355                Binder.restoreCallingIdentity(origId);
4356            }
4357        }
4358    }
4359
4360    @Override
4361    public final void finishHeavyWeightApp() {
4362        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4363                != PackageManager.PERMISSION_GRANTED) {
4364            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4365                    + Binder.getCallingPid()
4366                    + ", uid=" + Binder.getCallingUid()
4367                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4368            Slog.w(TAG, msg);
4369            throw new SecurityException(msg);
4370        }
4371
4372        synchronized(this) {
4373            if (mHeavyWeightProcess == null) {
4374                return;
4375            }
4376
4377            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4378                    mHeavyWeightProcess.activities);
4379            for (int i=0; i<activities.size(); i++) {
4380                ActivityRecord r = activities.get(i);
4381                if (!r.finishing) {
4382                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4383                            null, "finish-heavy", true);
4384                }
4385            }
4386
4387            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4388                    mHeavyWeightProcess.userId, 0));
4389            mHeavyWeightProcess = null;
4390        }
4391    }
4392
4393    @Override
4394    public void crashApplication(int uid, int initialPid, String packageName,
4395            String message) {
4396        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4397                != PackageManager.PERMISSION_GRANTED) {
4398            String msg = "Permission Denial: crashApplication() from pid="
4399                    + Binder.getCallingPid()
4400                    + ", uid=" + Binder.getCallingUid()
4401                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4402            Slog.w(TAG, msg);
4403            throw new SecurityException(msg);
4404        }
4405
4406        synchronized(this) {
4407            ProcessRecord proc = null;
4408
4409            // Figure out which process to kill.  We don't trust that initialPid
4410            // still has any relation to current pids, so must scan through the
4411            // list.
4412            synchronized (mPidsSelfLocked) {
4413                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4414                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4415                    if (p.uid != uid) {
4416                        continue;
4417                    }
4418                    if (p.pid == initialPid) {
4419                        proc = p;
4420                        break;
4421                    }
4422                    if (p.pkgList.containsKey(packageName)) {
4423                        proc = p;
4424                    }
4425                }
4426            }
4427
4428            if (proc == null) {
4429                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4430                        + " initialPid=" + initialPid
4431                        + " packageName=" + packageName);
4432                return;
4433            }
4434
4435            if (proc.thread != null) {
4436                if (proc.pid == Process.myPid()) {
4437                    Log.w(TAG, "crashApplication: trying to crash self!");
4438                    return;
4439                }
4440                long ident = Binder.clearCallingIdentity();
4441                try {
4442                    proc.thread.scheduleCrash(message);
4443                } catch (RemoteException e) {
4444                }
4445                Binder.restoreCallingIdentity(ident);
4446            }
4447        }
4448    }
4449
4450    @Override
4451    public final void finishSubActivity(IBinder token, String resultWho,
4452            int requestCode) {
4453        synchronized(this) {
4454            final long origId = Binder.clearCallingIdentity();
4455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4456            if (r != null) {
4457                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4458            }
4459            Binder.restoreCallingIdentity(origId);
4460        }
4461    }
4462
4463    @Override
4464    public boolean finishActivityAffinity(IBinder token) {
4465        synchronized(this) {
4466            final long origId = Binder.clearCallingIdentity();
4467            try {
4468                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4469
4470                ActivityRecord rootR = r.task.getRootActivity();
4471                // Do not allow task to finish in Lock Task mode.
4472                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4473                    if (rootR == r) {
4474                        mStackSupervisor.showLockTaskToast();
4475                        return false;
4476                    }
4477                }
4478                boolean res = false;
4479                if (r != null) {
4480                    res = r.task.stack.finishActivityAffinityLocked(r);
4481                }
4482                return res;
4483            } finally {
4484                Binder.restoreCallingIdentity(origId);
4485            }
4486        }
4487    }
4488
4489    @Override
4490    public void finishVoiceTask(IVoiceInteractionSession session) {
4491        synchronized(this) {
4492            final long origId = Binder.clearCallingIdentity();
4493            try {
4494                mStackSupervisor.finishVoiceTask(session);
4495            } finally {
4496                Binder.restoreCallingIdentity(origId);
4497            }
4498        }
4499
4500    }
4501
4502    @Override
4503    public boolean releaseActivityInstance(IBinder token) {
4504        synchronized(this) {
4505            final long origId = Binder.clearCallingIdentity();
4506            try {
4507                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4508                if (r.task == null || r.task.stack == null) {
4509                    return false;
4510                }
4511                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4512            } finally {
4513                Binder.restoreCallingIdentity(origId);
4514            }
4515        }
4516    }
4517
4518    @Override
4519    public void releaseSomeActivities(IApplicationThread appInt) {
4520        synchronized(this) {
4521            final long origId = Binder.clearCallingIdentity();
4522            try {
4523                ProcessRecord app = getRecordForAppLocked(appInt);
4524                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4525            } finally {
4526                Binder.restoreCallingIdentity(origId);
4527            }
4528        }
4529    }
4530
4531    @Override
4532    public boolean willActivityBeVisible(IBinder token) {
4533        synchronized(this) {
4534            ActivityStack stack = ActivityRecord.getStackLocked(token);
4535            if (stack != null) {
4536                return stack.willActivityBeVisibleLocked(token);
4537            }
4538            return false;
4539        }
4540    }
4541
4542    @Override
4543    public void overridePendingTransition(IBinder token, String packageName,
4544            int enterAnim, int exitAnim) {
4545        synchronized(this) {
4546            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4547            if (self == null) {
4548                return;
4549            }
4550
4551            final long origId = Binder.clearCallingIdentity();
4552
4553            if (self.state == ActivityState.RESUMED
4554                    || self.state == ActivityState.PAUSING) {
4555                mWindowManager.overridePendingAppTransition(packageName,
4556                        enterAnim, exitAnim, null);
4557            }
4558
4559            Binder.restoreCallingIdentity(origId);
4560        }
4561    }
4562
4563    /**
4564     * Main function for removing an existing process from the activity manager
4565     * as a result of that process going away.  Clears out all connections
4566     * to the process.
4567     */
4568    private final void handleAppDiedLocked(ProcessRecord app,
4569            boolean restarting, boolean allowRestart) {
4570        int pid = app.pid;
4571        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4572        if (!kept && !restarting) {
4573            removeLruProcessLocked(app);
4574            if (pid > 0) {
4575                ProcessList.remove(pid);
4576            }
4577        }
4578
4579        if (mProfileProc == app) {
4580            clearProfilerLocked();
4581        }
4582
4583        // Remove this application's activities from active lists.
4584        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4585
4586        app.activities.clear();
4587
4588        if (app.instrumentationClass != null) {
4589            Slog.w(TAG, "Crash of app " + app.processName
4590                  + " running instrumentation " + app.instrumentationClass);
4591            Bundle info = new Bundle();
4592            info.putString("shortMsg", "Process crashed.");
4593            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4594        }
4595
4596        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4597            // If there was nothing to resume, and we are not already
4598            // restarting this process, but there is a visible activity that
4599            // is hosted by the process...  then make sure all visible
4600            // activities are running, taking care of restarting this
4601            // process.
4602            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4603        }
4604    }
4605
4606    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4607        IBinder threadBinder = thread.asBinder();
4608        // Find the application record.
4609        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4610            ProcessRecord rec = mLruProcesses.get(i);
4611            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4612                return i;
4613            }
4614        }
4615        return -1;
4616    }
4617
4618    final ProcessRecord getRecordForAppLocked(
4619            IApplicationThread thread) {
4620        if (thread == null) {
4621            return null;
4622        }
4623
4624        int appIndex = getLRURecordIndexForAppLocked(thread);
4625        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4626    }
4627
4628    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4629        // If there are no longer any background processes running,
4630        // and the app that died was not running instrumentation,
4631        // then tell everyone we are now low on memory.
4632        boolean haveBg = false;
4633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4634            ProcessRecord rec = mLruProcesses.get(i);
4635            if (rec.thread != null
4636                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4637                haveBg = true;
4638                break;
4639            }
4640        }
4641
4642        if (!haveBg) {
4643            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4644            if (doReport) {
4645                long now = SystemClock.uptimeMillis();
4646                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4647                    doReport = false;
4648                } else {
4649                    mLastMemUsageReportTime = now;
4650                }
4651            }
4652            final ArrayList<ProcessMemInfo> memInfos
4653                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4654            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4655            long now = SystemClock.uptimeMillis();
4656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657                ProcessRecord rec = mLruProcesses.get(i);
4658                if (rec == dyingProc || rec.thread == null) {
4659                    continue;
4660                }
4661                if (doReport) {
4662                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4663                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4664                }
4665                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4666                    // The low memory report is overriding any current
4667                    // state for a GC request.  Make sure to do
4668                    // heavy/important/visible/foreground processes first.
4669                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4670                        rec.lastRequestedGc = 0;
4671                    } else {
4672                        rec.lastRequestedGc = rec.lastLowMemory;
4673                    }
4674                    rec.reportLowMemory = true;
4675                    rec.lastLowMemory = now;
4676                    mProcessesToGc.remove(rec);
4677                    addProcessToGcListLocked(rec);
4678                }
4679            }
4680            if (doReport) {
4681                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4682                mHandler.sendMessage(msg);
4683            }
4684            scheduleAppGcsLocked();
4685        }
4686    }
4687
4688    final void appDiedLocked(ProcessRecord app) {
4689       appDiedLocked(app, app.pid, app.thread, false);
4690    }
4691
4692    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4693            boolean fromBinderDied) {
4694        // First check if this ProcessRecord is actually active for the pid.
4695        synchronized (mPidsSelfLocked) {
4696            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4697            if (curProc != app) {
4698                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4699                return;
4700            }
4701        }
4702
4703        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4704        synchronized (stats) {
4705            stats.noteProcessDiedLocked(app.info.uid, pid);
4706        }
4707
4708        if (!app.killed) {
4709            if (!fromBinderDied) {
4710                Process.killProcessQuiet(pid);
4711            }
4712            Process.killProcessGroup(app.info.uid, pid);
4713            app.killed = true;
4714        }
4715
4716        // Clean up already done if the process has been re-started.
4717        if (app.pid == pid && app.thread != null &&
4718                app.thread.asBinder() == thread.asBinder()) {
4719            boolean doLowMem = app.instrumentationClass == null;
4720            boolean doOomAdj = doLowMem;
4721            if (!app.killedByAm) {
4722                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4723                        + ") has died");
4724                mAllowLowerMemLevel = true;
4725            } else {
4726                // Note that we always want to do oom adj to update our state with the
4727                // new number of procs.
4728                mAllowLowerMemLevel = false;
4729                doLowMem = false;
4730            }
4731            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4732            if (DEBUG_CLEANUP) Slog.v(
4733                TAG, "Dying app: " + app + ", pid: " + pid
4734                + ", thread: " + thread.asBinder());
4735            handleAppDiedLocked(app, false, true);
4736
4737            if (doOomAdj) {
4738                updateOomAdjLocked();
4739            }
4740            if (doLowMem) {
4741                doLowMemReportIfNeededLocked(app);
4742            }
4743        } else if (app.pid != pid) {
4744            // A new process has already been started.
4745            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4746                    + ") has died and restarted (pid " + app.pid + ").");
4747            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4748        } else if (DEBUG_PROCESSES) {
4749            Slog.d(TAG, "Received spurious death notification for thread "
4750                    + thread.asBinder());
4751        }
4752    }
4753
4754    /**
4755     * If a stack trace dump file is configured, dump process stack traces.
4756     * @param clearTraces causes the dump file to be erased prior to the new
4757     *    traces being written, if true; when false, the new traces will be
4758     *    appended to any existing file content.
4759     * @param firstPids of dalvik VM processes to dump stack traces for first
4760     * @param lastPids of dalvik VM processes to dump stack traces for last
4761     * @param nativeProcs optional list of native process names to dump stack crawls
4762     * @return file containing stack traces, or null if no dump file is configured
4763     */
4764    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4765            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4766        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4767        if (tracesPath == null || tracesPath.length() == 0) {
4768            return null;
4769        }
4770
4771        File tracesFile = new File(tracesPath);
4772        try {
4773            File tracesDir = tracesFile.getParentFile();
4774            if (!tracesDir.exists()) {
4775                tracesDir.mkdirs();
4776                if (!SELinux.restorecon(tracesDir)) {
4777                    return null;
4778                }
4779            }
4780            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4781
4782            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4783            tracesFile.createNewFile();
4784            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4785        } catch (IOException e) {
4786            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4787            return null;
4788        }
4789
4790        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4791        return tracesFile;
4792    }
4793
4794    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4795            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4796        // Use a FileObserver to detect when traces finish writing.
4797        // The order of traces is considered important to maintain for legibility.
4798        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4799            @Override
4800            public synchronized void onEvent(int event, String path) { notify(); }
4801        };
4802
4803        try {
4804            observer.startWatching();
4805
4806            // First collect all of the stacks of the most important pids.
4807            if (firstPids != null) {
4808                try {
4809                    int num = firstPids.size();
4810                    for (int i = 0; i < num; i++) {
4811                        synchronized (observer) {
4812                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4813                            observer.wait(200);  // Wait for write-close, give up after 200msec
4814                        }
4815                    }
4816                } catch (InterruptedException e) {
4817                    Slog.wtf(TAG, e);
4818                }
4819            }
4820
4821            // Next collect the stacks of the native pids
4822            if (nativeProcs != null) {
4823                int[] pids = Process.getPidsForCommands(nativeProcs);
4824                if (pids != null) {
4825                    for (int pid : pids) {
4826                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4827                    }
4828                }
4829            }
4830
4831            // Lastly, measure CPU usage.
4832            if (processCpuTracker != null) {
4833                processCpuTracker.init();
4834                System.gc();
4835                processCpuTracker.update();
4836                try {
4837                    synchronized (processCpuTracker) {
4838                        processCpuTracker.wait(500); // measure over 1/2 second.
4839                    }
4840                } catch (InterruptedException e) {
4841                }
4842                processCpuTracker.update();
4843
4844                // We'll take the stack crawls of just the top apps using CPU.
4845                final int N = processCpuTracker.countWorkingStats();
4846                int numProcs = 0;
4847                for (int i=0; i<N && numProcs<5; i++) {
4848                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4849                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4850                        numProcs++;
4851                        try {
4852                            synchronized (observer) {
4853                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4854                                observer.wait(200);  // Wait for write-close, give up after 200msec
4855                            }
4856                        } catch (InterruptedException e) {
4857                            Slog.wtf(TAG, e);
4858                        }
4859
4860                    }
4861                }
4862            }
4863        } finally {
4864            observer.stopWatching();
4865        }
4866    }
4867
4868    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4869        if (true || IS_USER_BUILD) {
4870            return;
4871        }
4872        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4873        if (tracesPath == null || tracesPath.length() == 0) {
4874            return;
4875        }
4876
4877        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4878        StrictMode.allowThreadDiskWrites();
4879        try {
4880            final File tracesFile = new File(tracesPath);
4881            final File tracesDir = tracesFile.getParentFile();
4882            final File tracesTmp = new File(tracesDir, "__tmp__");
4883            try {
4884                if (!tracesDir.exists()) {
4885                    tracesDir.mkdirs();
4886                    if (!SELinux.restorecon(tracesDir.getPath())) {
4887                        return;
4888                    }
4889                }
4890                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4891
4892                if (tracesFile.exists()) {
4893                    tracesTmp.delete();
4894                    tracesFile.renameTo(tracesTmp);
4895                }
4896                StringBuilder sb = new StringBuilder();
4897                Time tobj = new Time();
4898                tobj.set(System.currentTimeMillis());
4899                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4900                sb.append(": ");
4901                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4902                sb.append(" since ");
4903                sb.append(msg);
4904                FileOutputStream fos = new FileOutputStream(tracesFile);
4905                fos.write(sb.toString().getBytes());
4906                if (app == null) {
4907                    fos.write("\n*** No application process!".getBytes());
4908                }
4909                fos.close();
4910                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4911            } catch (IOException e) {
4912                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4913                return;
4914            }
4915
4916            if (app != null) {
4917                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4918                firstPids.add(app.pid);
4919                dumpStackTraces(tracesPath, firstPids, null, null, null);
4920            }
4921
4922            File lastTracesFile = null;
4923            File curTracesFile = null;
4924            for (int i=9; i>=0; i--) {
4925                String name = String.format(Locale.US, "slow%02d.txt", i);
4926                curTracesFile = new File(tracesDir, name);
4927                if (curTracesFile.exists()) {
4928                    if (lastTracesFile != null) {
4929                        curTracesFile.renameTo(lastTracesFile);
4930                    } else {
4931                        curTracesFile.delete();
4932                    }
4933                }
4934                lastTracesFile = curTracesFile;
4935            }
4936            tracesFile.renameTo(curTracesFile);
4937            if (tracesTmp.exists()) {
4938                tracesTmp.renameTo(tracesFile);
4939            }
4940        } finally {
4941            StrictMode.setThreadPolicy(oldPolicy);
4942        }
4943    }
4944
4945    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4946            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4947        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4948        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4949
4950        if (mController != null) {
4951            try {
4952                // 0 == continue, -1 = kill process immediately
4953                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4954                if (res < 0 && app.pid != MY_PID) {
4955                    app.kill("anr", true);
4956                }
4957            } catch (RemoteException e) {
4958                mController = null;
4959                Watchdog.getInstance().setActivityController(null);
4960            }
4961        }
4962
4963        long anrTime = SystemClock.uptimeMillis();
4964        if (MONITOR_CPU_USAGE) {
4965            updateCpuStatsNow();
4966        }
4967
4968        synchronized (this) {
4969            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4970            if (mShuttingDown) {
4971                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4972                return;
4973            } else if (app.notResponding) {
4974                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4975                return;
4976            } else if (app.crashing) {
4977                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4978                return;
4979            }
4980
4981            // In case we come through here for the same app before completing
4982            // this one, mark as anring now so we will bail out.
4983            app.notResponding = true;
4984
4985            // Log the ANR to the event log.
4986            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4987                    app.processName, app.info.flags, annotation);
4988
4989            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4990            firstPids.add(app.pid);
4991
4992            int parentPid = app.pid;
4993            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4994            if (parentPid != app.pid) firstPids.add(parentPid);
4995
4996            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4997
4998            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4999                ProcessRecord r = mLruProcesses.get(i);
5000                if (r != null && r.thread != null) {
5001                    int pid = r.pid;
5002                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5003                        if (r.persistent) {
5004                            firstPids.add(pid);
5005                        } else {
5006                            lastPids.put(pid, Boolean.TRUE);
5007                        }
5008                    }
5009                }
5010            }
5011        }
5012
5013        // Log the ANR to the main log.
5014        StringBuilder info = new StringBuilder();
5015        info.setLength(0);
5016        info.append("ANR in ").append(app.processName);
5017        if (activity != null && activity.shortComponentName != null) {
5018            info.append(" (").append(activity.shortComponentName).append(")");
5019        }
5020        info.append("\n");
5021        info.append("PID: ").append(app.pid).append("\n");
5022        if (annotation != null) {
5023            info.append("Reason: ").append(annotation).append("\n");
5024        }
5025        if (parent != null && parent != activity) {
5026            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5027        }
5028
5029        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5030
5031        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5032                NATIVE_STACKS_OF_INTEREST);
5033
5034        String cpuInfo = null;
5035        if (MONITOR_CPU_USAGE) {
5036            updateCpuStatsNow();
5037            synchronized (mProcessCpuTracker) {
5038                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5039            }
5040            info.append(processCpuTracker.printCurrentLoad());
5041            info.append(cpuInfo);
5042        }
5043
5044        info.append(processCpuTracker.printCurrentState(anrTime));
5045
5046        Slog.e(TAG, info.toString());
5047        if (tracesFile == null) {
5048            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5049            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5050        }
5051
5052        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5053                cpuInfo, tracesFile, null);
5054
5055        if (mController != null) {
5056            try {
5057                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5058                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5059                if (res != 0) {
5060                    if (res < 0 && app.pid != MY_PID) {
5061                        app.kill("anr", true);
5062                    } else {
5063                        synchronized (this) {
5064                            mServices.scheduleServiceTimeoutLocked(app);
5065                        }
5066                    }
5067                    return;
5068                }
5069            } catch (RemoteException e) {
5070                mController = null;
5071                Watchdog.getInstance().setActivityController(null);
5072            }
5073        }
5074
5075        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5076        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5077                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5078
5079        synchronized (this) {
5080            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5081
5082            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5083                app.kill("bg anr", true);
5084                return;
5085            }
5086
5087            // Set the app's notResponding state, and look up the errorReportReceiver
5088            makeAppNotRespondingLocked(app,
5089                    activity != null ? activity.shortComponentName : null,
5090                    annotation != null ? "ANR " + annotation : "ANR",
5091                    info.toString());
5092
5093            // Bring up the infamous App Not Responding dialog
5094            Message msg = Message.obtain();
5095            HashMap<String, Object> map = new HashMap<String, Object>();
5096            msg.what = SHOW_NOT_RESPONDING_MSG;
5097            msg.obj = map;
5098            msg.arg1 = aboveSystem ? 1 : 0;
5099            map.put("app", app);
5100            if (activity != null) {
5101                map.put("activity", activity);
5102            }
5103
5104            mHandler.sendMessage(msg);
5105        }
5106    }
5107
5108    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5109        if (!mLaunchWarningShown) {
5110            mLaunchWarningShown = true;
5111            mHandler.post(new Runnable() {
5112                @Override
5113                public void run() {
5114                    synchronized (ActivityManagerService.this) {
5115                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5116                        d.show();
5117                        mHandler.postDelayed(new Runnable() {
5118                            @Override
5119                            public void run() {
5120                                synchronized (ActivityManagerService.this) {
5121                                    d.dismiss();
5122                                    mLaunchWarningShown = false;
5123                                }
5124                            }
5125                        }, 4000);
5126                    }
5127                }
5128            });
5129        }
5130    }
5131
5132    @Override
5133    public boolean clearApplicationUserData(final String packageName,
5134            final IPackageDataObserver observer, int userId) {
5135        enforceNotIsolatedCaller("clearApplicationUserData");
5136        int uid = Binder.getCallingUid();
5137        int pid = Binder.getCallingPid();
5138        userId = handleIncomingUser(pid, uid,
5139                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5140        long callingId = Binder.clearCallingIdentity();
5141        try {
5142            IPackageManager pm = AppGlobals.getPackageManager();
5143            int pkgUid = -1;
5144            synchronized(this) {
5145                try {
5146                    pkgUid = pm.getPackageUid(packageName, userId);
5147                } catch (RemoteException e) {
5148                }
5149                if (pkgUid == -1) {
5150                    Slog.w(TAG, "Invalid packageName: " + packageName);
5151                    if (observer != null) {
5152                        try {
5153                            observer.onRemoveCompleted(packageName, false);
5154                        } catch (RemoteException e) {
5155                            Slog.i(TAG, "Observer no longer exists.");
5156                        }
5157                    }
5158                    return false;
5159                }
5160                if (uid == pkgUid || checkComponentPermission(
5161                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5162                        pid, uid, -1, true)
5163                        == PackageManager.PERMISSION_GRANTED) {
5164                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5165                } else {
5166                    throw new SecurityException("PID " + pid + " does not have permission "
5167                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5168                                    + " of package " + packageName);
5169                }
5170
5171                // Remove all tasks match the cleared application package and user
5172                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5173                    final TaskRecord tr = mRecentTasks.get(i);
5174                    final String taskPackageName =
5175                            tr.getBaseIntent().getComponent().getPackageName();
5176                    if (tr.userId != userId) continue;
5177                    if (!taskPackageName.equals(packageName)) continue;
5178                    removeTaskByIdLocked(tr.taskId, false);
5179                }
5180            }
5181
5182            try {
5183                // Clear application user data
5184                pm.clearApplicationUserData(packageName, observer, userId);
5185
5186                synchronized(this) {
5187                    // Remove all permissions granted from/to this package
5188                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5189                }
5190
5191                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5192                        Uri.fromParts("package", packageName, null));
5193                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5194                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5195                        null, null, 0, null, null, null, false, false, userId);
5196            } catch (RemoteException e) {
5197            }
5198        } finally {
5199            Binder.restoreCallingIdentity(callingId);
5200        }
5201        return true;
5202    }
5203
5204    @Override
5205    public void killBackgroundProcesses(final String packageName, int userId) {
5206        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5207                != PackageManager.PERMISSION_GRANTED &&
5208                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5209                        != PackageManager.PERMISSION_GRANTED) {
5210            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5211                    + Binder.getCallingPid()
5212                    + ", uid=" + Binder.getCallingUid()
5213                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5214            Slog.w(TAG, msg);
5215            throw new SecurityException(msg);
5216        }
5217
5218        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5219                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5220        long callingId = Binder.clearCallingIdentity();
5221        try {
5222            IPackageManager pm = AppGlobals.getPackageManager();
5223            synchronized(this) {
5224                int appId = -1;
5225                try {
5226                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5227                } catch (RemoteException e) {
5228                }
5229                if (appId == -1) {
5230                    Slog.w(TAG, "Invalid packageName: " + packageName);
5231                    return;
5232                }
5233                killPackageProcessesLocked(packageName, appId, userId,
5234                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5235            }
5236        } finally {
5237            Binder.restoreCallingIdentity(callingId);
5238        }
5239    }
5240
5241    @Override
5242    public void killAllBackgroundProcesses() {
5243        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5244                != PackageManager.PERMISSION_GRANTED) {
5245            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5246                    + Binder.getCallingPid()
5247                    + ", uid=" + Binder.getCallingUid()
5248                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5249            Slog.w(TAG, msg);
5250            throw new SecurityException(msg);
5251        }
5252
5253        long callingId = Binder.clearCallingIdentity();
5254        try {
5255            synchronized(this) {
5256                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5257                final int NP = mProcessNames.getMap().size();
5258                for (int ip=0; ip<NP; ip++) {
5259                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5260                    final int NA = apps.size();
5261                    for (int ia=0; ia<NA; ia++) {
5262                        ProcessRecord app = apps.valueAt(ia);
5263                        if (app.persistent) {
5264                            // we don't kill persistent processes
5265                            continue;
5266                        }
5267                        if (app.removed) {
5268                            procs.add(app);
5269                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5270                            app.removed = true;
5271                            procs.add(app);
5272                        }
5273                    }
5274                }
5275
5276                int N = procs.size();
5277                for (int i=0; i<N; i++) {
5278                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5279                }
5280                mAllowLowerMemLevel = true;
5281                updateOomAdjLocked();
5282                doLowMemReportIfNeededLocked(null);
5283            }
5284        } finally {
5285            Binder.restoreCallingIdentity(callingId);
5286        }
5287    }
5288
5289    @Override
5290    public void forceStopPackage(final String packageName, int userId) {
5291        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5292                != PackageManager.PERMISSION_GRANTED) {
5293            String msg = "Permission Denial: forceStopPackage() from pid="
5294                    + Binder.getCallingPid()
5295                    + ", uid=" + Binder.getCallingUid()
5296                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5297            Slog.w(TAG, msg);
5298            throw new SecurityException(msg);
5299        }
5300        final int callingPid = Binder.getCallingPid();
5301        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5302                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5303        long callingId = Binder.clearCallingIdentity();
5304        try {
5305            IPackageManager pm = AppGlobals.getPackageManager();
5306            synchronized(this) {
5307                int[] users = userId == UserHandle.USER_ALL
5308                        ? getUsersLocked() : new int[] { userId };
5309                for (int user : users) {
5310                    int pkgUid = -1;
5311                    try {
5312                        pkgUid = pm.getPackageUid(packageName, user);
5313                    } catch (RemoteException e) {
5314                    }
5315                    if (pkgUid == -1) {
5316                        Slog.w(TAG, "Invalid packageName: " + packageName);
5317                        continue;
5318                    }
5319                    try {
5320                        pm.setPackageStoppedState(packageName, true, user);
5321                    } catch (RemoteException e) {
5322                    } catch (IllegalArgumentException e) {
5323                        Slog.w(TAG, "Failed trying to unstop package "
5324                                + packageName + ": " + e);
5325                    }
5326                    if (isUserRunningLocked(user, false)) {
5327                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5328                    }
5329                }
5330            }
5331        } finally {
5332            Binder.restoreCallingIdentity(callingId);
5333        }
5334    }
5335
5336    @Override
5337    public void addPackageDependency(String packageName) {
5338        synchronized (this) {
5339            int callingPid = Binder.getCallingPid();
5340            if (callingPid == Process.myPid()) {
5341                //  Yeah, um, no.
5342                return;
5343            }
5344            ProcessRecord proc;
5345            synchronized (mPidsSelfLocked) {
5346                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5347            }
5348            if (proc != null) {
5349                if (proc.pkgDeps == null) {
5350                    proc.pkgDeps = new ArraySet<String>(1);
5351                }
5352                proc.pkgDeps.add(packageName);
5353            }
5354        }
5355    }
5356
5357    /*
5358     * The pkg name and app id have to be specified.
5359     */
5360    @Override
5361    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5362        if (pkg == null) {
5363            return;
5364        }
5365        // Make sure the uid is valid.
5366        if (appid < 0) {
5367            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5368            return;
5369        }
5370        int callerUid = Binder.getCallingUid();
5371        // Only the system server can kill an application
5372        if (callerUid == Process.SYSTEM_UID) {
5373            // Post an aysnc message to kill the application
5374            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5375            msg.arg1 = appid;
5376            msg.arg2 = 0;
5377            Bundle bundle = new Bundle();
5378            bundle.putString("pkg", pkg);
5379            bundle.putString("reason", reason);
5380            msg.obj = bundle;
5381            mHandler.sendMessage(msg);
5382        } else {
5383            throw new SecurityException(callerUid + " cannot kill pkg: " +
5384                    pkg);
5385        }
5386    }
5387
5388    @Override
5389    public void closeSystemDialogs(String reason) {
5390        enforceNotIsolatedCaller("closeSystemDialogs");
5391
5392        final int pid = Binder.getCallingPid();
5393        final int uid = Binder.getCallingUid();
5394        final long origId = Binder.clearCallingIdentity();
5395        try {
5396            synchronized (this) {
5397                // Only allow this from foreground processes, so that background
5398                // applications can't abuse it to prevent system UI from being shown.
5399                if (uid >= Process.FIRST_APPLICATION_UID) {
5400                    ProcessRecord proc;
5401                    synchronized (mPidsSelfLocked) {
5402                        proc = mPidsSelfLocked.get(pid);
5403                    }
5404                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5405                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5406                                + " from background process " + proc);
5407                        return;
5408                    }
5409                }
5410                closeSystemDialogsLocked(reason);
5411            }
5412        } finally {
5413            Binder.restoreCallingIdentity(origId);
5414        }
5415    }
5416
5417    void closeSystemDialogsLocked(String reason) {
5418        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5419        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5420                | Intent.FLAG_RECEIVER_FOREGROUND);
5421        if (reason != null) {
5422            intent.putExtra("reason", reason);
5423        }
5424        mWindowManager.closeSystemDialogs(reason);
5425
5426        mStackSupervisor.closeSystemDialogsLocked();
5427
5428        broadcastIntentLocked(null, null, intent, null,
5429                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5430                Process.SYSTEM_UID, UserHandle.USER_ALL);
5431    }
5432
5433    @Override
5434    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5435        enforceNotIsolatedCaller("getProcessMemoryInfo");
5436        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5437        for (int i=pids.length-1; i>=0; i--) {
5438            ProcessRecord proc;
5439            int oomAdj;
5440            synchronized (this) {
5441                synchronized (mPidsSelfLocked) {
5442                    proc = mPidsSelfLocked.get(pids[i]);
5443                    oomAdj = proc != null ? proc.setAdj : 0;
5444                }
5445            }
5446            infos[i] = new Debug.MemoryInfo();
5447            Debug.getMemoryInfo(pids[i], infos[i]);
5448            if (proc != null) {
5449                synchronized (this) {
5450                    if (proc.thread != null && proc.setAdj == oomAdj) {
5451                        // Record this for posterity if the process has been stable.
5452                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5453                                infos[i].getTotalUss(), false, proc.pkgList);
5454                    }
5455                }
5456            }
5457        }
5458        return infos;
5459    }
5460
5461    @Override
5462    public long[] getProcessPss(int[] pids) {
5463        enforceNotIsolatedCaller("getProcessPss");
5464        long[] pss = new long[pids.length];
5465        for (int i=pids.length-1; i>=0; i--) {
5466            ProcessRecord proc;
5467            int oomAdj;
5468            synchronized (this) {
5469                synchronized (mPidsSelfLocked) {
5470                    proc = mPidsSelfLocked.get(pids[i]);
5471                    oomAdj = proc != null ? proc.setAdj : 0;
5472                }
5473            }
5474            long[] tmpUss = new long[1];
5475            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5476            if (proc != null) {
5477                synchronized (this) {
5478                    if (proc.thread != null && proc.setAdj == oomAdj) {
5479                        // Record this for posterity if the process has been stable.
5480                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5481                    }
5482                }
5483            }
5484        }
5485        return pss;
5486    }
5487
5488    @Override
5489    public void killApplicationProcess(String processName, int uid) {
5490        if (processName == null) {
5491            return;
5492        }
5493
5494        int callerUid = Binder.getCallingUid();
5495        // Only the system server can kill an application
5496        if (callerUid == Process.SYSTEM_UID) {
5497            synchronized (this) {
5498                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5499                if (app != null && app.thread != null) {
5500                    try {
5501                        app.thread.scheduleSuicide();
5502                    } catch (RemoteException e) {
5503                        // If the other end already died, then our work here is done.
5504                    }
5505                } else {
5506                    Slog.w(TAG, "Process/uid not found attempting kill of "
5507                            + processName + " / " + uid);
5508                }
5509            }
5510        } else {
5511            throw new SecurityException(callerUid + " cannot kill app process: " +
5512                    processName);
5513        }
5514    }
5515
5516    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5517        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5518                false, true, false, false, UserHandle.getUserId(uid), reason);
5519        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5520                Uri.fromParts("package", packageName, null));
5521        if (!mProcessesReady) {
5522            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5523                    | Intent.FLAG_RECEIVER_FOREGROUND);
5524        }
5525        intent.putExtra(Intent.EXTRA_UID, uid);
5526        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5527        broadcastIntentLocked(null, null, intent,
5528                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5529                false, false,
5530                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5531    }
5532
5533    private void forceStopUserLocked(int userId, String reason) {
5534        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5535        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5536        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5537                | Intent.FLAG_RECEIVER_FOREGROUND);
5538        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5539        broadcastIntentLocked(null, null, intent,
5540                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5541                false, false,
5542                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5543    }
5544
5545    private final boolean killPackageProcessesLocked(String packageName, int appId,
5546            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5547            boolean doit, boolean evenPersistent, String reason) {
5548        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5549
5550        // Remove all processes this package may have touched: all with the
5551        // same UID (except for the system or root user), and all whose name
5552        // matches the package name.
5553        final int NP = mProcessNames.getMap().size();
5554        for (int ip=0; ip<NP; ip++) {
5555            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5556            final int NA = apps.size();
5557            for (int ia=0; ia<NA; ia++) {
5558                ProcessRecord app = apps.valueAt(ia);
5559                if (app.persistent && !evenPersistent) {
5560                    // we don't kill persistent processes
5561                    continue;
5562                }
5563                if (app.removed) {
5564                    if (doit) {
5565                        procs.add(app);
5566                    }
5567                    continue;
5568                }
5569
5570                // Skip process if it doesn't meet our oom adj requirement.
5571                if (app.setAdj < minOomAdj) {
5572                    continue;
5573                }
5574
5575                // If no package is specified, we call all processes under the
5576                // give user id.
5577                if (packageName == null) {
5578                    if (app.userId != userId) {
5579                        continue;
5580                    }
5581                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5582                        continue;
5583                    }
5584                // Package has been specified, we want to hit all processes
5585                // that match it.  We need to qualify this by the processes
5586                // that are running under the specified app and user ID.
5587                } else {
5588                    final boolean isDep = app.pkgDeps != null
5589                            && app.pkgDeps.contains(packageName);
5590                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5591                        continue;
5592                    }
5593                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5594                        continue;
5595                    }
5596                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5597                        continue;
5598                    }
5599                }
5600
5601                // Process has passed all conditions, kill it!
5602                if (!doit) {
5603                    return true;
5604                }
5605                app.removed = true;
5606                procs.add(app);
5607            }
5608        }
5609
5610        int N = procs.size();
5611        for (int i=0; i<N; i++) {
5612            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5613        }
5614        updateOomAdjLocked();
5615        return N > 0;
5616    }
5617
5618    private final boolean forceStopPackageLocked(String name, int appId,
5619            boolean callerWillRestart, boolean purgeCache, boolean doit,
5620            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5621        int i;
5622        int N;
5623
5624        if (userId == UserHandle.USER_ALL && name == null) {
5625            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5626        }
5627
5628        if (appId < 0 && name != null) {
5629            try {
5630                appId = UserHandle.getAppId(
5631                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5632            } catch (RemoteException e) {
5633            }
5634        }
5635
5636        if (doit) {
5637            if (name != null) {
5638                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5639                        + " user=" + userId + ": " + reason);
5640            } else {
5641                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5642            }
5643
5644            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5645            for (int ip=pmap.size()-1; ip>=0; ip--) {
5646                SparseArray<Long> ba = pmap.valueAt(ip);
5647                for (i=ba.size()-1; i>=0; i--) {
5648                    boolean remove = false;
5649                    final int entUid = ba.keyAt(i);
5650                    if (name != null) {
5651                        if (userId == UserHandle.USER_ALL) {
5652                            if (UserHandle.getAppId(entUid) == appId) {
5653                                remove = true;
5654                            }
5655                        } else {
5656                            if (entUid == UserHandle.getUid(userId, appId)) {
5657                                remove = true;
5658                            }
5659                        }
5660                    } else if (UserHandle.getUserId(entUid) == userId) {
5661                        remove = true;
5662                    }
5663                    if (remove) {
5664                        ba.removeAt(i);
5665                    }
5666                }
5667                if (ba.size() == 0) {
5668                    pmap.removeAt(ip);
5669                }
5670            }
5671        }
5672
5673        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5674                -100, callerWillRestart, true, doit, evenPersistent,
5675                name == null ? ("stop user " + userId) : ("stop " + name));
5676
5677        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5678            if (!doit) {
5679                return true;
5680            }
5681            didSomething = true;
5682        }
5683
5684        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5685            if (!doit) {
5686                return true;
5687            }
5688            didSomething = true;
5689        }
5690
5691        if (name == null) {
5692            // Remove all sticky broadcasts from this user.
5693            mStickyBroadcasts.remove(userId);
5694        }
5695
5696        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5697        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5698                userId, providers)) {
5699            if (!doit) {
5700                return true;
5701            }
5702            didSomething = true;
5703        }
5704        N = providers.size();
5705        for (i=0; i<N; i++) {
5706            removeDyingProviderLocked(null, providers.get(i), true);
5707        }
5708
5709        // Remove transient permissions granted from/to this package/user
5710        removeUriPermissionsForPackageLocked(name, userId, false);
5711
5712        if (name == null || uninstalling) {
5713            // Remove pending intents.  For now we only do this when force
5714            // stopping users, because we have some problems when doing this
5715            // for packages -- app widgets are not currently cleaned up for
5716            // such packages, so they can be left with bad pending intents.
5717            if (mIntentSenderRecords.size() > 0) {
5718                Iterator<WeakReference<PendingIntentRecord>> it
5719                        = mIntentSenderRecords.values().iterator();
5720                while (it.hasNext()) {
5721                    WeakReference<PendingIntentRecord> wpir = it.next();
5722                    if (wpir == null) {
5723                        it.remove();
5724                        continue;
5725                    }
5726                    PendingIntentRecord pir = wpir.get();
5727                    if (pir == null) {
5728                        it.remove();
5729                        continue;
5730                    }
5731                    if (name == null) {
5732                        // Stopping user, remove all objects for the user.
5733                        if (pir.key.userId != userId) {
5734                            // Not the same user, skip it.
5735                            continue;
5736                        }
5737                    } else {
5738                        if (UserHandle.getAppId(pir.uid) != appId) {
5739                            // Different app id, skip it.
5740                            continue;
5741                        }
5742                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5743                            // Different user, skip it.
5744                            continue;
5745                        }
5746                        if (!pir.key.packageName.equals(name)) {
5747                            // Different package, skip it.
5748                            continue;
5749                        }
5750                    }
5751                    if (!doit) {
5752                        return true;
5753                    }
5754                    didSomething = true;
5755                    it.remove();
5756                    pir.canceled = true;
5757                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5758                        pir.key.activity.pendingResults.remove(pir.ref);
5759                    }
5760                }
5761            }
5762        }
5763
5764        if (doit) {
5765            if (purgeCache && name != null) {
5766                AttributeCache ac = AttributeCache.instance();
5767                if (ac != null) {
5768                    ac.removePackage(name);
5769                }
5770            }
5771            if (mBooted) {
5772                mStackSupervisor.resumeTopActivitiesLocked();
5773                mStackSupervisor.scheduleIdleLocked();
5774            }
5775        }
5776
5777        return didSomething;
5778    }
5779
5780    private final boolean removeProcessLocked(ProcessRecord app,
5781            boolean callerWillRestart, boolean allowRestart, String reason) {
5782        final String name = app.processName;
5783        final int uid = app.uid;
5784        if (DEBUG_PROCESSES) Slog.d(
5785            TAG, "Force removing proc " + app.toShortString() + " (" + name
5786            + "/" + uid + ")");
5787
5788        mProcessNames.remove(name, uid);
5789        mIsolatedProcesses.remove(app.uid);
5790        if (mHeavyWeightProcess == app) {
5791            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5792                    mHeavyWeightProcess.userId, 0));
5793            mHeavyWeightProcess = null;
5794        }
5795        boolean needRestart = false;
5796        if (app.pid > 0 && app.pid != MY_PID) {
5797            int pid = app.pid;
5798            synchronized (mPidsSelfLocked) {
5799                mPidsSelfLocked.remove(pid);
5800                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5801            }
5802            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5803            if (app.isolated) {
5804                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5805            }
5806            app.kill(reason, true);
5807            handleAppDiedLocked(app, true, allowRestart);
5808            removeLruProcessLocked(app);
5809
5810            if (app.persistent && !app.isolated) {
5811                if (!callerWillRestart) {
5812                    addAppLocked(app.info, false, null /* ABI override */);
5813                } else {
5814                    needRestart = true;
5815                }
5816            }
5817        } else {
5818            mRemovedProcesses.add(app);
5819        }
5820
5821        return needRestart;
5822    }
5823
5824    private final void processStartTimedOutLocked(ProcessRecord app) {
5825        final int pid = app.pid;
5826        boolean gone = false;
5827        synchronized (mPidsSelfLocked) {
5828            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5829            if (knownApp != null && knownApp.thread == null) {
5830                mPidsSelfLocked.remove(pid);
5831                gone = true;
5832            }
5833        }
5834
5835        if (gone) {
5836            Slog.w(TAG, "Process " + app + " failed to attach");
5837            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5838                    pid, app.uid, app.processName);
5839            mProcessNames.remove(app.processName, app.uid);
5840            mIsolatedProcesses.remove(app.uid);
5841            if (mHeavyWeightProcess == app) {
5842                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5843                        mHeavyWeightProcess.userId, 0));
5844                mHeavyWeightProcess = null;
5845            }
5846            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5847            if (app.isolated) {
5848                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5849            }
5850            // Take care of any launching providers waiting for this process.
5851            checkAppInLaunchingProvidersLocked(app, true);
5852            // Take care of any services that are waiting for the process.
5853            mServices.processStartTimedOutLocked(app);
5854            app.kill("start timeout", true);
5855            removeLruProcessLocked(app);
5856            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5857                Slog.w(TAG, "Unattached app died before backup, skipping");
5858                try {
5859                    IBackupManager bm = IBackupManager.Stub.asInterface(
5860                            ServiceManager.getService(Context.BACKUP_SERVICE));
5861                    bm.agentDisconnected(app.info.packageName);
5862                } catch (RemoteException e) {
5863                    // Can't happen; the backup manager is local
5864                }
5865            }
5866            if (isPendingBroadcastProcessLocked(pid)) {
5867                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5868                skipPendingBroadcastLocked(pid);
5869            }
5870        } else {
5871            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5872        }
5873    }
5874
5875    private final boolean attachApplicationLocked(IApplicationThread thread,
5876            int pid) {
5877
5878        // Find the application record that is being attached...  either via
5879        // the pid if we are running in multiple processes, or just pull the
5880        // next app record if we are emulating process with anonymous threads.
5881        ProcessRecord app;
5882        if (pid != MY_PID && pid >= 0) {
5883            synchronized (mPidsSelfLocked) {
5884                app = mPidsSelfLocked.get(pid);
5885            }
5886        } else {
5887            app = null;
5888        }
5889
5890        if (app == null) {
5891            Slog.w(TAG, "No pending application record for pid " + pid
5892                    + " (IApplicationThread " + thread + "); dropping process");
5893            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5894            if (pid > 0 && pid != MY_PID) {
5895                Process.killProcessQuiet(pid);
5896                //TODO: Process.killProcessGroup(app.info.uid, pid);
5897            } else {
5898                try {
5899                    thread.scheduleExit();
5900                } catch (Exception e) {
5901                    // Ignore exceptions.
5902                }
5903            }
5904            return false;
5905        }
5906
5907        // If this application record is still attached to a previous
5908        // process, clean it up now.
5909        if (app.thread != null) {
5910            handleAppDiedLocked(app, true, true);
5911        }
5912
5913        // Tell the process all about itself.
5914
5915        if (localLOGV) Slog.v(
5916                TAG, "Binding process pid " + pid + " to record " + app);
5917
5918        final String processName = app.processName;
5919        try {
5920            AppDeathRecipient adr = new AppDeathRecipient(
5921                    app, pid, thread);
5922            thread.asBinder().linkToDeath(adr, 0);
5923            app.deathRecipient = adr;
5924        } catch (RemoteException e) {
5925            app.resetPackageList(mProcessStats);
5926            startProcessLocked(app, "link fail", processName);
5927            return false;
5928        }
5929
5930        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5931
5932        app.makeActive(thread, mProcessStats);
5933        app.curAdj = app.setAdj = -100;
5934        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5935        app.forcingToForeground = null;
5936        updateProcessForegroundLocked(app, false, false);
5937        app.hasShownUi = false;
5938        app.debugging = false;
5939        app.cached = false;
5940        app.killedByAm = false;
5941
5942        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5943
5944        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5945        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5946
5947        if (!normalMode) {
5948            Slog.i(TAG, "Launching preboot mode app: " + app);
5949        }
5950
5951        if (localLOGV) Slog.v(
5952            TAG, "New app record " + app
5953            + " thread=" + thread.asBinder() + " pid=" + pid);
5954        try {
5955            int testMode = IApplicationThread.DEBUG_OFF;
5956            if (mDebugApp != null && mDebugApp.equals(processName)) {
5957                testMode = mWaitForDebugger
5958                    ? IApplicationThread.DEBUG_WAIT
5959                    : IApplicationThread.DEBUG_ON;
5960                app.debugging = true;
5961                if (mDebugTransient) {
5962                    mDebugApp = mOrigDebugApp;
5963                    mWaitForDebugger = mOrigWaitForDebugger;
5964                }
5965            }
5966            String profileFile = app.instrumentationProfileFile;
5967            ParcelFileDescriptor profileFd = null;
5968            int samplingInterval = 0;
5969            boolean profileAutoStop = false;
5970            if (mProfileApp != null && mProfileApp.equals(processName)) {
5971                mProfileProc = app;
5972                profileFile = mProfileFile;
5973                profileFd = mProfileFd;
5974                samplingInterval = mSamplingInterval;
5975                profileAutoStop = mAutoStopProfiler;
5976            }
5977            boolean enableOpenGlTrace = false;
5978            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5979                enableOpenGlTrace = true;
5980                mOpenGlTraceApp = null;
5981            }
5982
5983            // If the app is being launched for restore or full backup, set it up specially
5984            boolean isRestrictedBackupMode = false;
5985            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5986                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5987                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5988                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5989            }
5990
5991            ensurePackageDexOpt(app.instrumentationInfo != null
5992                    ? app.instrumentationInfo.packageName
5993                    : app.info.packageName);
5994            if (app.instrumentationClass != null) {
5995                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5996            }
5997            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5998                    + processName + " with config " + mConfiguration);
5999            ApplicationInfo appInfo = app.instrumentationInfo != null
6000                    ? app.instrumentationInfo : app.info;
6001            app.compat = compatibilityInfoForPackageLocked(appInfo);
6002            if (profileFd != null) {
6003                profileFd = profileFd.dup();
6004            }
6005            ProfilerInfo profilerInfo = profileFile == null ? null
6006                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6007            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6008                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6009                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6010                    isRestrictedBackupMode || !normalMode, app.persistent,
6011                    new Configuration(mConfiguration), app.compat,
6012                    getCommonServicesLocked(app.isolated),
6013                    mCoreSettingsObserver.getCoreSettingsLocked());
6014            updateLruProcessLocked(app, false, null);
6015            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6016        } catch (Exception e) {
6017            // todo: Yikes!  What should we do?  For now we will try to
6018            // start another process, but that could easily get us in
6019            // an infinite loop of restarting processes...
6020            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6021
6022            app.resetPackageList(mProcessStats);
6023            app.unlinkDeathRecipient();
6024            startProcessLocked(app, "bind fail", processName);
6025            return false;
6026        }
6027
6028        // Remove this record from the list of starting applications.
6029        mPersistentStartingProcesses.remove(app);
6030        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6031                "Attach application locked removing on hold: " + app);
6032        mProcessesOnHold.remove(app);
6033
6034        boolean badApp = false;
6035        boolean didSomething = false;
6036
6037        // See if the top visible activity is waiting to run in this process...
6038        if (normalMode) {
6039            try {
6040                if (mStackSupervisor.attachApplicationLocked(app)) {
6041                    didSomething = true;
6042                }
6043            } catch (Exception e) {
6044                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6045                badApp = true;
6046            }
6047        }
6048
6049        // Find any services that should be running in this process...
6050        if (!badApp) {
6051            try {
6052                didSomething |= mServices.attachApplicationLocked(app, processName);
6053            } catch (Exception e) {
6054                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6055                badApp = true;
6056            }
6057        }
6058
6059        // Check if a next-broadcast receiver is in this process...
6060        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6061            try {
6062                didSomething |= sendPendingBroadcastsLocked(app);
6063            } catch (Exception e) {
6064                // If the app died trying to launch the receiver we declare it 'bad'
6065                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6066                badApp = true;
6067            }
6068        }
6069
6070        // Check whether the next backup agent is in this process...
6071        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6072            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6073            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6074            try {
6075                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6076                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6077                        mBackupTarget.backupMode);
6078            } catch (Exception e) {
6079                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6080                badApp = true;
6081            }
6082        }
6083
6084        if (badApp) {
6085            app.kill("error during init", true);
6086            handleAppDiedLocked(app, false, true);
6087            return false;
6088        }
6089
6090        if (!didSomething) {
6091            updateOomAdjLocked();
6092        }
6093
6094        return true;
6095    }
6096
6097    @Override
6098    public final void attachApplication(IApplicationThread thread) {
6099        synchronized (this) {
6100            int callingPid = Binder.getCallingPid();
6101            final long origId = Binder.clearCallingIdentity();
6102            attachApplicationLocked(thread, callingPid);
6103            Binder.restoreCallingIdentity(origId);
6104        }
6105    }
6106
6107    @Override
6108    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6109        final long origId = Binder.clearCallingIdentity();
6110        synchronized (this) {
6111            ActivityStack stack = ActivityRecord.getStackLocked(token);
6112            if (stack != null) {
6113                ActivityRecord r =
6114                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6115                if (stopProfiling) {
6116                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6117                        try {
6118                            mProfileFd.close();
6119                        } catch (IOException e) {
6120                        }
6121                        clearProfilerLocked();
6122                    }
6123                }
6124            }
6125        }
6126        Binder.restoreCallingIdentity(origId);
6127    }
6128
6129    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6130        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6131                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6132    }
6133
6134    void enableScreenAfterBoot() {
6135        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6136                SystemClock.uptimeMillis());
6137        mWindowManager.enableScreenAfterBoot();
6138
6139        synchronized (this) {
6140            updateEventDispatchingLocked();
6141        }
6142    }
6143
6144    @Override
6145    public void showBootMessage(final CharSequence msg, final boolean always) {
6146        enforceNotIsolatedCaller("showBootMessage");
6147        mWindowManager.showBootMessage(msg, always);
6148    }
6149
6150    @Override
6151    public void keyguardWaitingForActivityDrawn() {
6152        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6153        final long token = Binder.clearCallingIdentity();
6154        try {
6155            synchronized (this) {
6156                if (DEBUG_LOCKSCREEN) logLockScreen("");
6157                mWindowManager.keyguardWaitingForActivityDrawn();
6158                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6159                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6160                    updateSleepIfNeededLocked();
6161                }
6162            }
6163        } finally {
6164            Binder.restoreCallingIdentity(token);
6165        }
6166    }
6167
6168    final void finishBooting() {
6169        synchronized (this) {
6170            if (!mBootAnimationComplete) {
6171                mCallFinishBooting = true;
6172                return;
6173            }
6174            mCallFinishBooting = false;
6175        }
6176
6177        ArraySet<String> completedIsas = new ArraySet<String>();
6178        for (String abi : Build.SUPPORTED_ABIS) {
6179            Process.establishZygoteConnectionForAbi(abi);
6180            final String instructionSet = VMRuntime.getInstructionSet(abi);
6181            if (!completedIsas.contains(instructionSet)) {
6182                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6183                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6184                }
6185                completedIsas.add(instructionSet);
6186            }
6187        }
6188
6189        IntentFilter pkgFilter = new IntentFilter();
6190        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6191        pkgFilter.addDataScheme("package");
6192        mContext.registerReceiver(new BroadcastReceiver() {
6193            @Override
6194            public void onReceive(Context context, Intent intent) {
6195                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6196                if (pkgs != null) {
6197                    for (String pkg : pkgs) {
6198                        synchronized (ActivityManagerService.this) {
6199                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6200                                    0, "finished booting")) {
6201                                setResultCode(Activity.RESULT_OK);
6202                                return;
6203                            }
6204                        }
6205                    }
6206                }
6207            }
6208        }, pkgFilter);
6209
6210        // Let system services know.
6211        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6212
6213        synchronized (this) {
6214            // Ensure that any processes we had put on hold are now started
6215            // up.
6216            final int NP = mProcessesOnHold.size();
6217            if (NP > 0) {
6218                ArrayList<ProcessRecord> procs =
6219                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6220                for (int ip=0; ip<NP; ip++) {
6221                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6222                            + procs.get(ip));
6223                    startProcessLocked(procs.get(ip), "on-hold", null);
6224                }
6225            }
6226
6227            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6228                // Start looking for apps that are abusing wake locks.
6229                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6230                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6231                // Tell anyone interested that we are done booting!
6232                SystemProperties.set("sys.boot_completed", "1");
6233
6234                // And trigger dev.bootcomplete if we are not showing encryption progress
6235                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6236                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6237                    SystemProperties.set("dev.bootcomplete", "1");
6238                }
6239                for (int i=0; i<mStartedUsers.size(); i++) {
6240                    UserStartedState uss = mStartedUsers.valueAt(i);
6241                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6242                        uss.mState = UserStartedState.STATE_RUNNING;
6243                        final int userId = mStartedUsers.keyAt(i);
6244                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6245                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6246                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6247                        broadcastIntentLocked(null, null, intent, null,
6248                                new IIntentReceiver.Stub() {
6249                                    @Override
6250                                    public void performReceive(Intent intent, int resultCode,
6251                                            String data, Bundle extras, boolean ordered,
6252                                            boolean sticky, int sendingUser) {
6253                                        synchronized (ActivityManagerService.this) {
6254                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6255                                                    true, false);
6256                                        }
6257                                    }
6258                                },
6259                                0, null, null,
6260                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6261                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6262                                userId);
6263                    }
6264                }
6265                scheduleStartProfilesLocked();
6266            }
6267        }
6268    }
6269
6270    @Override
6271    public void bootAnimationComplete() {
6272        final boolean callFinishBooting;
6273        synchronized (this) {
6274            callFinishBooting = mCallFinishBooting;
6275            mBootAnimationComplete = true;
6276        }
6277        if (callFinishBooting) {
6278            finishBooting();
6279        }
6280    }
6281
6282    @Override
6283    public void systemBackupRestored() {
6284        synchronized (this) {
6285            if (mSystemReady) {
6286                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6287            } else {
6288                Slog.w(TAG, "System backup restored before system is ready");
6289            }
6290        }
6291    }
6292
6293    final void ensureBootCompleted() {
6294        boolean booting;
6295        boolean enableScreen;
6296        synchronized (this) {
6297            booting = mBooting;
6298            mBooting = false;
6299            enableScreen = !mBooted;
6300            mBooted = true;
6301        }
6302
6303        if (booting) {
6304            finishBooting();
6305        }
6306
6307        if (enableScreen) {
6308            enableScreenAfterBoot();
6309        }
6310    }
6311
6312    @Override
6313    public final void activityResumed(IBinder token) {
6314        final long origId = Binder.clearCallingIdentity();
6315        synchronized(this) {
6316            ActivityStack stack = ActivityRecord.getStackLocked(token);
6317            if (stack != null) {
6318                ActivityRecord.activityResumedLocked(token);
6319            }
6320        }
6321        Binder.restoreCallingIdentity(origId);
6322    }
6323
6324    @Override
6325    public final void activityPaused(IBinder token) {
6326        final long origId = Binder.clearCallingIdentity();
6327        synchronized(this) {
6328            ActivityStack stack = ActivityRecord.getStackLocked(token);
6329            if (stack != null) {
6330                stack.activityPausedLocked(token, false);
6331            }
6332        }
6333        Binder.restoreCallingIdentity(origId);
6334    }
6335
6336    @Override
6337    public final void activityStopped(IBinder token, Bundle icicle,
6338            PersistableBundle persistentState, CharSequence description) {
6339        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6340
6341        // Refuse possible leaked file descriptors
6342        if (icicle != null && icicle.hasFileDescriptors()) {
6343            throw new IllegalArgumentException("File descriptors passed in Bundle");
6344        }
6345
6346        final long origId = Binder.clearCallingIdentity();
6347
6348        synchronized (this) {
6349            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6350            if (r != null) {
6351                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6352            }
6353        }
6354
6355        trimApplications();
6356
6357        Binder.restoreCallingIdentity(origId);
6358    }
6359
6360    @Override
6361    public final void activityDestroyed(IBinder token) {
6362        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6363        synchronized (this) {
6364            ActivityStack stack = ActivityRecord.getStackLocked(token);
6365            if (stack != null) {
6366                stack.activityDestroyedLocked(token, "activityDestroyed");
6367            }
6368        }
6369    }
6370
6371    @Override
6372    public final void backgroundResourcesReleased(IBinder token) {
6373        final long origId = Binder.clearCallingIdentity();
6374        try {
6375            synchronized (this) {
6376                ActivityStack stack = ActivityRecord.getStackLocked(token);
6377                if (stack != null) {
6378                    stack.backgroundResourcesReleased();
6379                }
6380            }
6381        } finally {
6382            Binder.restoreCallingIdentity(origId);
6383        }
6384    }
6385
6386    @Override
6387    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6388        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6389    }
6390
6391    @Override
6392    public final void notifyEnterAnimationComplete(IBinder token) {
6393        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6394    }
6395
6396    @Override
6397    public String getCallingPackage(IBinder token) {
6398        synchronized (this) {
6399            ActivityRecord r = getCallingRecordLocked(token);
6400            return r != null ? r.info.packageName : null;
6401        }
6402    }
6403
6404    @Override
6405    public ComponentName getCallingActivity(IBinder token) {
6406        synchronized (this) {
6407            ActivityRecord r = getCallingRecordLocked(token);
6408            return r != null ? r.intent.getComponent() : null;
6409        }
6410    }
6411
6412    private ActivityRecord getCallingRecordLocked(IBinder token) {
6413        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6414        if (r == null) {
6415            return null;
6416        }
6417        return r.resultTo;
6418    }
6419
6420    @Override
6421    public ComponentName getActivityClassForToken(IBinder token) {
6422        synchronized(this) {
6423            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6424            if (r == null) {
6425                return null;
6426            }
6427            return r.intent.getComponent();
6428        }
6429    }
6430
6431    @Override
6432    public String getPackageForToken(IBinder token) {
6433        synchronized(this) {
6434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6435            if (r == null) {
6436                return null;
6437            }
6438            return r.packageName;
6439        }
6440    }
6441
6442    @Override
6443    public IIntentSender getIntentSender(int type,
6444            String packageName, IBinder token, String resultWho,
6445            int requestCode, Intent[] intents, String[] resolvedTypes,
6446            int flags, Bundle options, int userId) {
6447        enforceNotIsolatedCaller("getIntentSender");
6448        // Refuse possible leaked file descriptors
6449        if (intents != null) {
6450            if (intents.length < 1) {
6451                throw new IllegalArgumentException("Intents array length must be >= 1");
6452            }
6453            for (int i=0; i<intents.length; i++) {
6454                Intent intent = intents[i];
6455                if (intent != null) {
6456                    if (intent.hasFileDescriptors()) {
6457                        throw new IllegalArgumentException("File descriptors passed in Intent");
6458                    }
6459                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6460                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6461                        throw new IllegalArgumentException(
6462                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6463                    }
6464                    intents[i] = new Intent(intent);
6465                }
6466            }
6467            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6468                throw new IllegalArgumentException(
6469                        "Intent array length does not match resolvedTypes length");
6470            }
6471        }
6472        if (options != null) {
6473            if (options.hasFileDescriptors()) {
6474                throw new IllegalArgumentException("File descriptors passed in options");
6475            }
6476        }
6477
6478        synchronized(this) {
6479            int callingUid = Binder.getCallingUid();
6480            int origUserId = userId;
6481            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6482                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6483                    ALLOW_NON_FULL, "getIntentSender", null);
6484            if (origUserId == UserHandle.USER_CURRENT) {
6485                // We don't want to evaluate this until the pending intent is
6486                // actually executed.  However, we do want to always do the
6487                // security checking for it above.
6488                userId = UserHandle.USER_CURRENT;
6489            }
6490            try {
6491                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6492                    int uid = AppGlobals.getPackageManager()
6493                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6494                    if (!UserHandle.isSameApp(callingUid, uid)) {
6495                        String msg = "Permission Denial: getIntentSender() from pid="
6496                            + Binder.getCallingPid()
6497                            + ", uid=" + Binder.getCallingUid()
6498                            + ", (need uid=" + uid + ")"
6499                            + " is not allowed to send as package " + packageName;
6500                        Slog.w(TAG, msg);
6501                        throw new SecurityException(msg);
6502                    }
6503                }
6504
6505                return getIntentSenderLocked(type, packageName, callingUid, userId,
6506                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6507
6508            } catch (RemoteException e) {
6509                throw new SecurityException(e);
6510            }
6511        }
6512    }
6513
6514    IIntentSender getIntentSenderLocked(int type, String packageName,
6515            int callingUid, int userId, IBinder token, String resultWho,
6516            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6517            Bundle options) {
6518        if (DEBUG_MU)
6519            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6520        ActivityRecord activity = null;
6521        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6522            activity = ActivityRecord.isInStackLocked(token);
6523            if (activity == null) {
6524                return null;
6525            }
6526            if (activity.finishing) {
6527                return null;
6528            }
6529        }
6530
6531        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6532        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6533        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6534        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6535                |PendingIntent.FLAG_UPDATE_CURRENT);
6536
6537        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6538                type, packageName, activity, resultWho,
6539                requestCode, intents, resolvedTypes, flags, options, userId);
6540        WeakReference<PendingIntentRecord> ref;
6541        ref = mIntentSenderRecords.get(key);
6542        PendingIntentRecord rec = ref != null ? ref.get() : null;
6543        if (rec != null) {
6544            if (!cancelCurrent) {
6545                if (updateCurrent) {
6546                    if (rec.key.requestIntent != null) {
6547                        rec.key.requestIntent.replaceExtras(intents != null ?
6548                                intents[intents.length - 1] : null);
6549                    }
6550                    if (intents != null) {
6551                        intents[intents.length-1] = rec.key.requestIntent;
6552                        rec.key.allIntents = intents;
6553                        rec.key.allResolvedTypes = resolvedTypes;
6554                    } else {
6555                        rec.key.allIntents = null;
6556                        rec.key.allResolvedTypes = null;
6557                    }
6558                }
6559                return rec;
6560            }
6561            rec.canceled = true;
6562            mIntentSenderRecords.remove(key);
6563        }
6564        if (noCreate) {
6565            return rec;
6566        }
6567        rec = new PendingIntentRecord(this, key, callingUid);
6568        mIntentSenderRecords.put(key, rec.ref);
6569        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6570            if (activity.pendingResults == null) {
6571                activity.pendingResults
6572                        = new HashSet<WeakReference<PendingIntentRecord>>();
6573            }
6574            activity.pendingResults.add(rec.ref);
6575        }
6576        return rec;
6577    }
6578
6579    @Override
6580    public void cancelIntentSender(IIntentSender sender) {
6581        if (!(sender instanceof PendingIntentRecord)) {
6582            return;
6583        }
6584        synchronized(this) {
6585            PendingIntentRecord rec = (PendingIntentRecord)sender;
6586            try {
6587                int uid = AppGlobals.getPackageManager()
6588                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6589                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6590                    String msg = "Permission Denial: cancelIntentSender() from pid="
6591                        + Binder.getCallingPid()
6592                        + ", uid=" + Binder.getCallingUid()
6593                        + " is not allowed to cancel packges "
6594                        + rec.key.packageName;
6595                    Slog.w(TAG, msg);
6596                    throw new SecurityException(msg);
6597                }
6598            } catch (RemoteException e) {
6599                throw new SecurityException(e);
6600            }
6601            cancelIntentSenderLocked(rec, true);
6602        }
6603    }
6604
6605    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6606        rec.canceled = true;
6607        mIntentSenderRecords.remove(rec.key);
6608        if (cleanActivity && rec.key.activity != null) {
6609            rec.key.activity.pendingResults.remove(rec.ref);
6610        }
6611    }
6612
6613    @Override
6614    public String getPackageForIntentSender(IIntentSender pendingResult) {
6615        if (!(pendingResult instanceof PendingIntentRecord)) {
6616            return null;
6617        }
6618        try {
6619            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6620            return res.key.packageName;
6621        } catch (ClassCastException e) {
6622        }
6623        return null;
6624    }
6625
6626    @Override
6627    public int getUidForIntentSender(IIntentSender sender) {
6628        if (sender instanceof PendingIntentRecord) {
6629            try {
6630                PendingIntentRecord res = (PendingIntentRecord)sender;
6631                return res.uid;
6632            } catch (ClassCastException e) {
6633            }
6634        }
6635        return -1;
6636    }
6637
6638    @Override
6639    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6640        if (!(pendingResult instanceof PendingIntentRecord)) {
6641            return false;
6642        }
6643        try {
6644            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6645            if (res.key.allIntents == null) {
6646                return false;
6647            }
6648            for (int i=0; i<res.key.allIntents.length; i++) {
6649                Intent intent = res.key.allIntents[i];
6650                if (intent.getPackage() != null && intent.getComponent() != null) {
6651                    return false;
6652                }
6653            }
6654            return true;
6655        } catch (ClassCastException e) {
6656        }
6657        return false;
6658    }
6659
6660    @Override
6661    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6662        if (!(pendingResult instanceof PendingIntentRecord)) {
6663            return false;
6664        }
6665        try {
6666            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6667            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6668                return true;
6669            }
6670            return false;
6671        } catch (ClassCastException e) {
6672        }
6673        return false;
6674    }
6675
6676    @Override
6677    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6678        if (!(pendingResult instanceof PendingIntentRecord)) {
6679            return null;
6680        }
6681        try {
6682            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6683            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6684        } catch (ClassCastException e) {
6685        }
6686        return null;
6687    }
6688
6689    @Override
6690    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6691        if (!(pendingResult instanceof PendingIntentRecord)) {
6692            return null;
6693        }
6694        try {
6695            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6696            Intent intent = res.key.requestIntent;
6697            if (intent != null) {
6698                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6699                        || res.lastTagPrefix.equals(prefix))) {
6700                    return res.lastTag;
6701                }
6702                res.lastTagPrefix = prefix;
6703                StringBuilder sb = new StringBuilder(128);
6704                if (prefix != null) {
6705                    sb.append(prefix);
6706                }
6707                if (intent.getAction() != null) {
6708                    sb.append(intent.getAction());
6709                } else if (intent.getComponent() != null) {
6710                    intent.getComponent().appendShortString(sb);
6711                } else {
6712                    sb.append("?");
6713                }
6714                return res.lastTag = sb.toString();
6715            }
6716        } catch (ClassCastException e) {
6717        }
6718        return null;
6719    }
6720
6721    @Override
6722    public void setProcessLimit(int max) {
6723        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6724                "setProcessLimit()");
6725        synchronized (this) {
6726            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6727            mProcessLimitOverride = max;
6728        }
6729        trimApplications();
6730    }
6731
6732    @Override
6733    public int getProcessLimit() {
6734        synchronized (this) {
6735            return mProcessLimitOverride;
6736        }
6737    }
6738
6739    void foregroundTokenDied(ForegroundToken token) {
6740        synchronized (ActivityManagerService.this) {
6741            synchronized (mPidsSelfLocked) {
6742                ForegroundToken cur
6743                    = mForegroundProcesses.get(token.pid);
6744                if (cur != token) {
6745                    return;
6746                }
6747                mForegroundProcesses.remove(token.pid);
6748                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6749                if (pr == null) {
6750                    return;
6751                }
6752                pr.forcingToForeground = null;
6753                updateProcessForegroundLocked(pr, false, false);
6754            }
6755            updateOomAdjLocked();
6756        }
6757    }
6758
6759    @Override
6760    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6761        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6762                "setProcessForeground()");
6763        synchronized(this) {
6764            boolean changed = false;
6765
6766            synchronized (mPidsSelfLocked) {
6767                ProcessRecord pr = mPidsSelfLocked.get(pid);
6768                if (pr == null && isForeground) {
6769                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6770                    return;
6771                }
6772                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6773                if (oldToken != null) {
6774                    oldToken.token.unlinkToDeath(oldToken, 0);
6775                    mForegroundProcesses.remove(pid);
6776                    if (pr != null) {
6777                        pr.forcingToForeground = null;
6778                    }
6779                    changed = true;
6780                }
6781                if (isForeground && token != null) {
6782                    ForegroundToken newToken = new ForegroundToken() {
6783                        @Override
6784                        public void binderDied() {
6785                            foregroundTokenDied(this);
6786                        }
6787                    };
6788                    newToken.pid = pid;
6789                    newToken.token = token;
6790                    try {
6791                        token.linkToDeath(newToken, 0);
6792                        mForegroundProcesses.put(pid, newToken);
6793                        pr.forcingToForeground = token;
6794                        changed = true;
6795                    } catch (RemoteException e) {
6796                        // If the process died while doing this, we will later
6797                        // do the cleanup with the process death link.
6798                    }
6799                }
6800            }
6801
6802            if (changed) {
6803                updateOomAdjLocked();
6804            }
6805        }
6806    }
6807
6808    // =========================================================
6809    // PROCESS INFO
6810    // =========================================================
6811
6812    static class ProcessInfoService extends IProcessInfoService.Stub {
6813        final ActivityManagerService mActivityManagerService;
6814        ProcessInfoService(ActivityManagerService activityManagerService) {
6815            mActivityManagerService = activityManagerService;
6816        }
6817
6818        @Override
6819        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6820            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6821        }
6822    }
6823
6824    /**
6825     * For each PID in the given input array, write the current process state
6826     * for that process into the output array, or -1 to indicate that no
6827     * process with the given PID exists.
6828     */
6829    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6830        if (pids == null) {
6831            throw new NullPointerException("pids");
6832        } else if (states == null) {
6833            throw new NullPointerException("states");
6834        } else if (pids.length != states.length) {
6835            throw new IllegalArgumentException("input and output arrays have different lengths!");
6836        }
6837
6838        synchronized (mPidsSelfLocked) {
6839            for (int i = 0; i < pids.length; i++) {
6840                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6841                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6842                        pr.curProcState;
6843            }
6844        }
6845    }
6846
6847    // =========================================================
6848    // PERMISSIONS
6849    // =========================================================
6850
6851    static class PermissionController extends IPermissionController.Stub {
6852        ActivityManagerService mActivityManagerService;
6853        PermissionController(ActivityManagerService activityManagerService) {
6854            mActivityManagerService = activityManagerService;
6855        }
6856
6857        @Override
6858        public boolean checkPermission(String permission, int pid, int uid) {
6859            return mActivityManagerService.checkPermission(permission, pid,
6860                    uid) == PackageManager.PERMISSION_GRANTED;
6861        }
6862    }
6863
6864    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6865        @Override
6866        public int checkComponentPermission(String permission, int pid, int uid,
6867                int owningUid, boolean exported) {
6868            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6869                    owningUid, exported);
6870        }
6871
6872        @Override
6873        public Object getAMSLock() {
6874            return ActivityManagerService.this;
6875        }
6876    }
6877
6878    /**
6879     * This can be called with or without the global lock held.
6880     */
6881    int checkComponentPermission(String permission, int pid, int uid,
6882            int owningUid, boolean exported) {
6883        if (pid == MY_PID) {
6884            return PackageManager.PERMISSION_GRANTED;
6885        }
6886        return ActivityManager.checkComponentPermission(permission, uid,
6887                owningUid, exported);
6888    }
6889
6890    /**
6891     * As the only public entry point for permissions checking, this method
6892     * can enforce the semantic that requesting a check on a null global
6893     * permission is automatically denied.  (Internally a null permission
6894     * string is used when calling {@link #checkComponentPermission} in cases
6895     * when only uid-based security is needed.)
6896     *
6897     * This can be called with or without the global lock held.
6898     */
6899    @Override
6900    public int checkPermission(String permission, int pid, int uid) {
6901        if (permission == null) {
6902            return PackageManager.PERMISSION_DENIED;
6903        }
6904        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6905    }
6906
6907    @Override
6908    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6909        if (permission == null) {
6910            return PackageManager.PERMISSION_DENIED;
6911        }
6912
6913        // We might be performing an operation on behalf of an indirect binder
6914        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6915        // client identity accordingly before proceeding.
6916        Identity tlsIdentity = sCallerIdentity.get();
6917        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6918            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6919                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6920            uid = tlsIdentity.uid;
6921            pid = tlsIdentity.pid;
6922        }
6923
6924        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6925    }
6926
6927    /**
6928     * Binder IPC calls go through the public entry point.
6929     * This can be called with or without the global lock held.
6930     */
6931    int checkCallingPermission(String permission) {
6932        return checkPermission(permission,
6933                Binder.getCallingPid(),
6934                UserHandle.getAppId(Binder.getCallingUid()));
6935    }
6936
6937    /**
6938     * This can be called with or without the global lock held.
6939     */
6940    void enforceCallingPermission(String permission, String func) {
6941        if (checkCallingPermission(permission)
6942                == PackageManager.PERMISSION_GRANTED) {
6943            return;
6944        }
6945
6946        String msg = "Permission Denial: " + func + " from pid="
6947                + Binder.getCallingPid()
6948                + ", uid=" + Binder.getCallingUid()
6949                + " requires " + permission;
6950        Slog.w(TAG, msg);
6951        throw new SecurityException(msg);
6952    }
6953
6954    /**
6955     * Determine if UID is holding permissions required to access {@link Uri} in
6956     * the given {@link ProviderInfo}. Final permission checking is always done
6957     * in {@link ContentProvider}.
6958     */
6959    private final boolean checkHoldingPermissionsLocked(
6960            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6961        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6962                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6963        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6964            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6965                    != PERMISSION_GRANTED) {
6966                return false;
6967            }
6968        }
6969        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6970    }
6971
6972    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6973            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6974        if (pi.applicationInfo.uid == uid) {
6975            return true;
6976        } else if (!pi.exported) {
6977            return false;
6978        }
6979
6980        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6981        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6982        try {
6983            // check if target holds top-level <provider> permissions
6984            if (!readMet && pi.readPermission != null && considerUidPermissions
6985                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6986                readMet = true;
6987            }
6988            if (!writeMet && pi.writePermission != null && considerUidPermissions
6989                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6990                writeMet = true;
6991            }
6992
6993            // track if unprotected read/write is allowed; any denied
6994            // <path-permission> below removes this ability
6995            boolean allowDefaultRead = pi.readPermission == null;
6996            boolean allowDefaultWrite = pi.writePermission == null;
6997
6998            // check if target holds any <path-permission> that match uri
6999            final PathPermission[] pps = pi.pathPermissions;
7000            if (pps != null) {
7001                final String path = grantUri.uri.getPath();
7002                int i = pps.length;
7003                while (i > 0 && (!readMet || !writeMet)) {
7004                    i--;
7005                    PathPermission pp = pps[i];
7006                    if (pp.match(path)) {
7007                        if (!readMet) {
7008                            final String pprperm = pp.getReadPermission();
7009                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7010                                    + pprperm + " for " + pp.getPath()
7011                                    + ": match=" + pp.match(path)
7012                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7013                            if (pprperm != null) {
7014                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7015                                        == PERMISSION_GRANTED) {
7016                                    readMet = true;
7017                                } else {
7018                                    allowDefaultRead = false;
7019                                }
7020                            }
7021                        }
7022                        if (!writeMet) {
7023                            final String ppwperm = pp.getWritePermission();
7024                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7025                                    + ppwperm + " for " + pp.getPath()
7026                                    + ": match=" + pp.match(path)
7027                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7028                            if (ppwperm != null) {
7029                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7030                                        == PERMISSION_GRANTED) {
7031                                    writeMet = true;
7032                                } else {
7033                                    allowDefaultWrite = false;
7034                                }
7035                            }
7036                        }
7037                    }
7038                }
7039            }
7040
7041            // grant unprotected <provider> read/write, if not blocked by
7042            // <path-permission> above
7043            if (allowDefaultRead) readMet = true;
7044            if (allowDefaultWrite) writeMet = true;
7045
7046        } catch (RemoteException e) {
7047            return false;
7048        }
7049
7050        return readMet && writeMet;
7051    }
7052
7053    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7054        ProviderInfo pi = null;
7055        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7056        if (cpr != null) {
7057            pi = cpr.info;
7058        } else {
7059            try {
7060                pi = AppGlobals.getPackageManager().resolveContentProvider(
7061                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7062            } catch (RemoteException ex) {
7063            }
7064        }
7065        return pi;
7066    }
7067
7068    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7069        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7070        if (targetUris != null) {
7071            return targetUris.get(grantUri);
7072        }
7073        return null;
7074    }
7075
7076    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7077            String targetPkg, int targetUid, GrantUri grantUri) {
7078        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7079        if (targetUris == null) {
7080            targetUris = Maps.newArrayMap();
7081            mGrantedUriPermissions.put(targetUid, targetUris);
7082        }
7083
7084        UriPermission perm = targetUris.get(grantUri);
7085        if (perm == null) {
7086            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7087            targetUris.put(grantUri, perm);
7088        }
7089
7090        return perm;
7091    }
7092
7093    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7094            final int modeFlags) {
7095        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7096        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7097                : UriPermission.STRENGTH_OWNED;
7098
7099        // Root gets to do everything.
7100        if (uid == 0) {
7101            return true;
7102        }
7103
7104        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7105        if (perms == null) return false;
7106
7107        // First look for exact match
7108        final UriPermission exactPerm = perms.get(grantUri);
7109        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7110            return true;
7111        }
7112
7113        // No exact match, look for prefixes
7114        final int N = perms.size();
7115        for (int i = 0; i < N; i++) {
7116            final UriPermission perm = perms.valueAt(i);
7117            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7118                    && perm.getStrength(modeFlags) >= minStrength) {
7119                return true;
7120            }
7121        }
7122
7123        return false;
7124    }
7125
7126    /**
7127     * @param uri This uri must NOT contain an embedded userId.
7128     * @param userId The userId in which the uri is to be resolved.
7129     */
7130    @Override
7131    public int checkUriPermission(Uri uri, int pid, int uid,
7132            final int modeFlags, int userId, IBinder callerToken) {
7133        enforceNotIsolatedCaller("checkUriPermission");
7134
7135        // Another redirected-binder-call permissions check as in
7136        // {@link checkPermissionWithToken}.
7137        Identity tlsIdentity = sCallerIdentity.get();
7138        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7139            uid = tlsIdentity.uid;
7140            pid = tlsIdentity.pid;
7141        }
7142
7143        // Our own process gets to do everything.
7144        if (pid == MY_PID) {
7145            return PackageManager.PERMISSION_GRANTED;
7146        }
7147        synchronized (this) {
7148            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7149                    ? PackageManager.PERMISSION_GRANTED
7150                    : PackageManager.PERMISSION_DENIED;
7151        }
7152    }
7153
7154    /**
7155     * Check if the targetPkg can be granted permission to access uri by
7156     * the callingUid using the given modeFlags.  Throws a security exception
7157     * if callingUid is not allowed to do this.  Returns the uid of the target
7158     * if the URI permission grant should be performed; returns -1 if it is not
7159     * needed (for example targetPkg already has permission to access the URI).
7160     * If you already know the uid of the target, you can supply it in
7161     * lastTargetUid else set that to -1.
7162     */
7163    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7164            final int modeFlags, int lastTargetUid) {
7165        if (!Intent.isAccessUriMode(modeFlags)) {
7166            return -1;
7167        }
7168
7169        if (targetPkg != null) {
7170            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7171                    "Checking grant " + targetPkg + " permission to " + grantUri);
7172        }
7173
7174        final IPackageManager pm = AppGlobals.getPackageManager();
7175
7176        // If this is not a content: uri, we can't do anything with it.
7177        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7178            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7179                    "Can't grant URI permission for non-content URI: " + grantUri);
7180            return -1;
7181        }
7182
7183        final String authority = grantUri.uri.getAuthority();
7184        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7185        if (pi == null) {
7186            Slog.w(TAG, "No content provider found for permission check: " +
7187                    grantUri.uri.toSafeString());
7188            return -1;
7189        }
7190
7191        int targetUid = lastTargetUid;
7192        if (targetUid < 0 && targetPkg != null) {
7193            try {
7194                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7195                if (targetUid < 0) {
7196                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7197                            "Can't grant URI permission no uid for: " + targetPkg);
7198                    return -1;
7199                }
7200            } catch (RemoteException ex) {
7201                return -1;
7202            }
7203        }
7204
7205        if (targetUid >= 0) {
7206            // First...  does the target actually need this permission?
7207            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7208                // No need to grant the target this permission.
7209                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7210                        "Target " + targetPkg + " already has full permission to " + grantUri);
7211                return -1;
7212            }
7213        } else {
7214            // First...  there is no target package, so can anyone access it?
7215            boolean allowed = pi.exported;
7216            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7217                if (pi.readPermission != null) {
7218                    allowed = false;
7219                }
7220            }
7221            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7222                if (pi.writePermission != null) {
7223                    allowed = false;
7224                }
7225            }
7226            if (allowed) {
7227                return -1;
7228            }
7229        }
7230
7231        /* There is a special cross user grant if:
7232         * - The target is on another user.
7233         * - Apps on the current user can access the uri without any uid permissions.
7234         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7235         * grant uri permissions.
7236         */
7237        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7238                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7239                modeFlags, false /*without considering the uid permissions*/);
7240
7241        // Second...  is the provider allowing granting of URI permissions?
7242        if (!specialCrossUserGrant) {
7243            if (!pi.grantUriPermissions) {
7244                throw new SecurityException("Provider " + pi.packageName
7245                        + "/" + pi.name
7246                        + " does not allow granting of Uri permissions (uri "
7247                        + grantUri + ")");
7248            }
7249            if (pi.uriPermissionPatterns != null) {
7250                final int N = pi.uriPermissionPatterns.length;
7251                boolean allowed = false;
7252                for (int i=0; i<N; i++) {
7253                    if (pi.uriPermissionPatterns[i] != null
7254                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7255                        allowed = true;
7256                        break;
7257                    }
7258                }
7259                if (!allowed) {
7260                    throw new SecurityException("Provider " + pi.packageName
7261                            + "/" + pi.name
7262                            + " does not allow granting of permission to path of Uri "
7263                            + grantUri);
7264                }
7265            }
7266        }
7267
7268        // Third...  does the caller itself have permission to access
7269        // this uri?
7270        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7271            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7272                // Require they hold a strong enough Uri permission
7273                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7274                    throw new SecurityException("Uid " + callingUid
7275                            + " does not have permission to uri " + grantUri);
7276                }
7277            }
7278        }
7279        return targetUid;
7280    }
7281
7282    /**
7283     * @param uri This uri must NOT contain an embedded userId.
7284     * @param userId The userId in which the uri is to be resolved.
7285     */
7286    @Override
7287    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7288            final int modeFlags, int userId) {
7289        enforceNotIsolatedCaller("checkGrantUriPermission");
7290        synchronized(this) {
7291            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7292                    new GrantUri(userId, uri, false), modeFlags, -1);
7293        }
7294    }
7295
7296    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7297            final int modeFlags, UriPermissionOwner owner) {
7298        if (!Intent.isAccessUriMode(modeFlags)) {
7299            return;
7300        }
7301
7302        // So here we are: the caller has the assumed permission
7303        // to the uri, and the target doesn't.  Let's now give this to
7304        // the target.
7305
7306        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7307                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7308
7309        final String authority = grantUri.uri.getAuthority();
7310        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7311        if (pi == null) {
7312            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7313            return;
7314        }
7315
7316        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7317            grantUri.prefix = true;
7318        }
7319        final UriPermission perm = findOrCreateUriPermissionLocked(
7320                pi.packageName, targetPkg, targetUid, grantUri);
7321        perm.grantModes(modeFlags, owner);
7322    }
7323
7324    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7325            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7326        if (targetPkg == null) {
7327            throw new NullPointerException("targetPkg");
7328        }
7329        int targetUid;
7330        final IPackageManager pm = AppGlobals.getPackageManager();
7331        try {
7332            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7333        } catch (RemoteException ex) {
7334            return;
7335        }
7336
7337        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7338                targetUid);
7339        if (targetUid < 0) {
7340            return;
7341        }
7342
7343        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7344                owner);
7345    }
7346
7347    static class NeededUriGrants extends ArrayList<GrantUri> {
7348        final String targetPkg;
7349        final int targetUid;
7350        final int flags;
7351
7352        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7353            this.targetPkg = targetPkg;
7354            this.targetUid = targetUid;
7355            this.flags = flags;
7356        }
7357    }
7358
7359    /**
7360     * Like checkGrantUriPermissionLocked, but takes an Intent.
7361     */
7362    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7363            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7364        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7365                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7366                + " clip=" + (intent != null ? intent.getClipData() : null)
7367                + " from " + intent + "; flags=0x"
7368                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7369
7370        if (targetPkg == null) {
7371            throw new NullPointerException("targetPkg");
7372        }
7373
7374        if (intent == null) {
7375            return null;
7376        }
7377        Uri data = intent.getData();
7378        ClipData clip = intent.getClipData();
7379        if (data == null && clip == null) {
7380            return null;
7381        }
7382        // Default userId for uris in the intent (if they don't specify it themselves)
7383        int contentUserHint = intent.getContentUserHint();
7384        if (contentUserHint == UserHandle.USER_CURRENT) {
7385            contentUserHint = UserHandle.getUserId(callingUid);
7386        }
7387        final IPackageManager pm = AppGlobals.getPackageManager();
7388        int targetUid;
7389        if (needed != null) {
7390            targetUid = needed.targetUid;
7391        } else {
7392            try {
7393                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7394            } catch (RemoteException ex) {
7395                return null;
7396            }
7397            if (targetUid < 0) {
7398                if (DEBUG_URI_PERMISSION) {
7399                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7400                            + " on user " + targetUserId);
7401                }
7402                return null;
7403            }
7404        }
7405        if (data != null) {
7406            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7407            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7408                    targetUid);
7409            if (targetUid > 0) {
7410                if (needed == null) {
7411                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7412                }
7413                needed.add(grantUri);
7414            }
7415        }
7416        if (clip != null) {
7417            for (int i=0; i<clip.getItemCount(); i++) {
7418                Uri uri = clip.getItemAt(i).getUri();
7419                if (uri != null) {
7420                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7421                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7422                            targetUid);
7423                    if (targetUid > 0) {
7424                        if (needed == null) {
7425                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7426                        }
7427                        needed.add(grantUri);
7428                    }
7429                } else {
7430                    Intent clipIntent = clip.getItemAt(i).getIntent();
7431                    if (clipIntent != null) {
7432                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7433                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7434                        if (newNeeded != null) {
7435                            needed = newNeeded;
7436                        }
7437                    }
7438                }
7439            }
7440        }
7441
7442        return needed;
7443    }
7444
7445    /**
7446     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7447     */
7448    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7449            UriPermissionOwner owner) {
7450        if (needed != null) {
7451            for (int i=0; i<needed.size(); i++) {
7452                GrantUri grantUri = needed.get(i);
7453                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7454                        grantUri, needed.flags, owner);
7455            }
7456        }
7457    }
7458
7459    void grantUriPermissionFromIntentLocked(int callingUid,
7460            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7461        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7462                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7463        if (needed == null) {
7464            return;
7465        }
7466
7467        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7468    }
7469
7470    /**
7471     * @param uri This uri must NOT contain an embedded userId.
7472     * @param userId The userId in which the uri is to be resolved.
7473     */
7474    @Override
7475    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7476            final int modeFlags, int userId) {
7477        enforceNotIsolatedCaller("grantUriPermission");
7478        GrantUri grantUri = new GrantUri(userId, uri, false);
7479        synchronized(this) {
7480            final ProcessRecord r = getRecordForAppLocked(caller);
7481            if (r == null) {
7482                throw new SecurityException("Unable to find app for caller "
7483                        + caller
7484                        + " when granting permission to uri " + grantUri);
7485            }
7486            if (targetPkg == null) {
7487                throw new IllegalArgumentException("null target");
7488            }
7489            if (grantUri == null) {
7490                throw new IllegalArgumentException("null uri");
7491            }
7492
7493            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7494                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7495                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7496                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7497
7498            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7499                    UserHandle.getUserId(r.uid));
7500        }
7501    }
7502
7503    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7504        if (perm.modeFlags == 0) {
7505            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7506                    perm.targetUid);
7507            if (perms != null) {
7508                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7509                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7510
7511                perms.remove(perm.uri);
7512                if (perms.isEmpty()) {
7513                    mGrantedUriPermissions.remove(perm.targetUid);
7514                }
7515            }
7516        }
7517    }
7518
7519    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7520        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7521
7522        final IPackageManager pm = AppGlobals.getPackageManager();
7523        final String authority = grantUri.uri.getAuthority();
7524        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7525        if (pi == null) {
7526            Slog.w(TAG, "No content provider found for permission revoke: "
7527                    + grantUri.toSafeString());
7528            return;
7529        }
7530
7531        // Does the caller have this permission on the URI?
7532        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7533            // If they don't have direct access to the URI, then revoke any
7534            // ownerless URI permissions that have been granted to them.
7535            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7536            if (perms != null) {
7537                boolean persistChanged = false;
7538                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7539                    final UriPermission perm = it.next();
7540                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7541                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7542                        if (DEBUG_URI_PERMISSION)
7543                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7544                                    " permission to " + perm.uri);
7545                        persistChanged |= perm.revokeModes(
7546                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7547                        if (perm.modeFlags == 0) {
7548                            it.remove();
7549                        }
7550                    }
7551                }
7552                if (perms.isEmpty()) {
7553                    mGrantedUriPermissions.remove(callingUid);
7554                }
7555                if (persistChanged) {
7556                    schedulePersistUriGrants();
7557                }
7558            }
7559            return;
7560        }
7561
7562        boolean persistChanged = false;
7563
7564        // Go through all of the permissions and remove any that match.
7565        int N = mGrantedUriPermissions.size();
7566        for (int i = 0; i < N; i++) {
7567            final int targetUid = mGrantedUriPermissions.keyAt(i);
7568            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7569
7570            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7571                final UriPermission perm = it.next();
7572                if (perm.uri.sourceUserId == grantUri.sourceUserId
7573                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7574                    if (DEBUG_URI_PERMISSION)
7575                        Slog.v(TAG,
7576                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7577                    persistChanged |= perm.revokeModes(
7578                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7579                    if (perm.modeFlags == 0) {
7580                        it.remove();
7581                    }
7582                }
7583            }
7584
7585            if (perms.isEmpty()) {
7586                mGrantedUriPermissions.remove(targetUid);
7587                N--;
7588                i--;
7589            }
7590        }
7591
7592        if (persistChanged) {
7593            schedulePersistUriGrants();
7594        }
7595    }
7596
7597    /**
7598     * @param uri This uri must NOT contain an embedded userId.
7599     * @param userId The userId in which the uri is to be resolved.
7600     */
7601    @Override
7602    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7603            int userId) {
7604        enforceNotIsolatedCaller("revokeUriPermission");
7605        synchronized(this) {
7606            final ProcessRecord r = getRecordForAppLocked(caller);
7607            if (r == null) {
7608                throw new SecurityException("Unable to find app for caller "
7609                        + caller
7610                        + " when revoking permission to uri " + uri);
7611            }
7612            if (uri == null) {
7613                Slog.w(TAG, "revokeUriPermission: null uri");
7614                return;
7615            }
7616
7617            if (!Intent.isAccessUriMode(modeFlags)) {
7618                return;
7619            }
7620
7621            final IPackageManager pm = AppGlobals.getPackageManager();
7622            final String authority = uri.getAuthority();
7623            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7624            if (pi == null) {
7625                Slog.w(TAG, "No content provider found for permission revoke: "
7626                        + uri.toSafeString());
7627                return;
7628            }
7629
7630            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7631        }
7632    }
7633
7634    /**
7635     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7636     * given package.
7637     *
7638     * @param packageName Package name to match, or {@code null} to apply to all
7639     *            packages.
7640     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7641     *            to all users.
7642     * @param persistable If persistable grants should be removed.
7643     */
7644    private void removeUriPermissionsForPackageLocked(
7645            String packageName, int userHandle, boolean persistable) {
7646        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7647            throw new IllegalArgumentException("Must narrow by either package or user");
7648        }
7649
7650        boolean persistChanged = false;
7651
7652        int N = mGrantedUriPermissions.size();
7653        for (int i = 0; i < N; i++) {
7654            final int targetUid = mGrantedUriPermissions.keyAt(i);
7655            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7656
7657            // Only inspect grants matching user
7658            if (userHandle == UserHandle.USER_ALL
7659                    || userHandle == UserHandle.getUserId(targetUid)) {
7660                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7661                    final UriPermission perm = it.next();
7662
7663                    // Only inspect grants matching package
7664                    if (packageName == null || perm.sourcePkg.equals(packageName)
7665                            || perm.targetPkg.equals(packageName)) {
7666                        persistChanged |= perm.revokeModes(persistable
7667                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7668
7669                        // Only remove when no modes remain; any persisted grants
7670                        // will keep this alive.
7671                        if (perm.modeFlags == 0) {
7672                            it.remove();
7673                        }
7674                    }
7675                }
7676
7677                if (perms.isEmpty()) {
7678                    mGrantedUriPermissions.remove(targetUid);
7679                    N--;
7680                    i--;
7681                }
7682            }
7683        }
7684
7685        if (persistChanged) {
7686            schedulePersistUriGrants();
7687        }
7688    }
7689
7690    @Override
7691    public IBinder newUriPermissionOwner(String name) {
7692        enforceNotIsolatedCaller("newUriPermissionOwner");
7693        synchronized(this) {
7694            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7695            return owner.getExternalTokenLocked();
7696        }
7697    }
7698
7699    /**
7700     * @param uri This uri must NOT contain an embedded userId.
7701     * @param sourceUserId The userId in which the uri is to be resolved.
7702     * @param targetUserId The userId of the app that receives the grant.
7703     */
7704    @Override
7705    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7706            final int modeFlags, int sourceUserId, int targetUserId) {
7707        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7708                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7709        synchronized(this) {
7710            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7711            if (owner == null) {
7712                throw new IllegalArgumentException("Unknown owner: " + token);
7713            }
7714            if (fromUid != Binder.getCallingUid()) {
7715                if (Binder.getCallingUid() != Process.myUid()) {
7716                    // Only system code can grant URI permissions on behalf
7717                    // of other users.
7718                    throw new SecurityException("nice try");
7719                }
7720            }
7721            if (targetPkg == null) {
7722                throw new IllegalArgumentException("null target");
7723            }
7724            if (uri == null) {
7725                throw new IllegalArgumentException("null uri");
7726            }
7727
7728            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7729                    modeFlags, owner, targetUserId);
7730        }
7731    }
7732
7733    /**
7734     * @param uri This uri must NOT contain an embedded userId.
7735     * @param userId The userId in which the uri is to be resolved.
7736     */
7737    @Override
7738    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7739        synchronized(this) {
7740            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7741            if (owner == null) {
7742                throw new IllegalArgumentException("Unknown owner: " + token);
7743            }
7744
7745            if (uri == null) {
7746                owner.removeUriPermissionsLocked(mode);
7747            } else {
7748                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7749            }
7750        }
7751    }
7752
7753    private void schedulePersistUriGrants() {
7754        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7755            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7756                    10 * DateUtils.SECOND_IN_MILLIS);
7757        }
7758    }
7759
7760    private void writeGrantedUriPermissions() {
7761        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7762
7763        // Snapshot permissions so we can persist without lock
7764        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7765        synchronized (this) {
7766            final int size = mGrantedUriPermissions.size();
7767            for (int i = 0; i < size; i++) {
7768                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7769                for (UriPermission perm : perms.values()) {
7770                    if (perm.persistedModeFlags != 0) {
7771                        persist.add(perm.snapshot());
7772                    }
7773                }
7774            }
7775        }
7776
7777        FileOutputStream fos = null;
7778        try {
7779            fos = mGrantFile.startWrite();
7780
7781            XmlSerializer out = new FastXmlSerializer();
7782            out.setOutput(fos, "utf-8");
7783            out.startDocument(null, true);
7784            out.startTag(null, TAG_URI_GRANTS);
7785            for (UriPermission.Snapshot perm : persist) {
7786                out.startTag(null, TAG_URI_GRANT);
7787                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7788                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7789                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7790                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7791                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7792                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7793                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7794                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7795                out.endTag(null, TAG_URI_GRANT);
7796            }
7797            out.endTag(null, TAG_URI_GRANTS);
7798            out.endDocument();
7799
7800            mGrantFile.finishWrite(fos);
7801        } catch (IOException e) {
7802            if (fos != null) {
7803                mGrantFile.failWrite(fos);
7804            }
7805        }
7806    }
7807
7808    private void readGrantedUriPermissionsLocked() {
7809        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7810
7811        final long now = System.currentTimeMillis();
7812
7813        FileInputStream fis = null;
7814        try {
7815            fis = mGrantFile.openRead();
7816            final XmlPullParser in = Xml.newPullParser();
7817            in.setInput(fis, null);
7818
7819            int type;
7820            while ((type = in.next()) != END_DOCUMENT) {
7821                final String tag = in.getName();
7822                if (type == START_TAG) {
7823                    if (TAG_URI_GRANT.equals(tag)) {
7824                        final int sourceUserId;
7825                        final int targetUserId;
7826                        final int userHandle = readIntAttribute(in,
7827                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7828                        if (userHandle != UserHandle.USER_NULL) {
7829                            // For backwards compatibility.
7830                            sourceUserId = userHandle;
7831                            targetUserId = userHandle;
7832                        } else {
7833                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7834                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7835                        }
7836                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7837                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7838                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7839                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7840                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7841                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7842
7843                        // Sanity check that provider still belongs to source package
7844                        final ProviderInfo pi = getProviderInfoLocked(
7845                                uri.getAuthority(), sourceUserId);
7846                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7847                            int targetUid = -1;
7848                            try {
7849                                targetUid = AppGlobals.getPackageManager()
7850                                        .getPackageUid(targetPkg, targetUserId);
7851                            } catch (RemoteException e) {
7852                            }
7853                            if (targetUid != -1) {
7854                                final UriPermission perm = findOrCreateUriPermissionLocked(
7855                                        sourcePkg, targetPkg, targetUid,
7856                                        new GrantUri(sourceUserId, uri, prefix));
7857                                perm.initPersistedModes(modeFlags, createdTime);
7858                            }
7859                        } else {
7860                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7861                                    + " but instead found " + pi);
7862                        }
7863                    }
7864                }
7865            }
7866        } catch (FileNotFoundException e) {
7867            // Missing grants is okay
7868        } catch (IOException e) {
7869            Slog.wtf(TAG, "Failed reading Uri grants", e);
7870        } catch (XmlPullParserException e) {
7871            Slog.wtf(TAG, "Failed reading Uri grants", e);
7872        } finally {
7873            IoUtils.closeQuietly(fis);
7874        }
7875    }
7876
7877    /**
7878     * @param uri This uri must NOT contain an embedded userId.
7879     * @param userId The userId in which the uri is to be resolved.
7880     */
7881    @Override
7882    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7883        enforceNotIsolatedCaller("takePersistableUriPermission");
7884
7885        Preconditions.checkFlagsArgument(modeFlags,
7886                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7887
7888        synchronized (this) {
7889            final int callingUid = Binder.getCallingUid();
7890            boolean persistChanged = false;
7891            GrantUri grantUri = new GrantUri(userId, uri, false);
7892
7893            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7894                    new GrantUri(userId, uri, false));
7895            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7896                    new GrantUri(userId, uri, true));
7897
7898            final boolean exactValid = (exactPerm != null)
7899                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7900            final boolean prefixValid = (prefixPerm != null)
7901                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7902
7903            if (!(exactValid || prefixValid)) {
7904                throw new SecurityException("No persistable permission grants found for UID "
7905                        + callingUid + " and Uri " + grantUri.toSafeString());
7906            }
7907
7908            if (exactValid) {
7909                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7910            }
7911            if (prefixValid) {
7912                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7913            }
7914
7915            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7916
7917            if (persistChanged) {
7918                schedulePersistUriGrants();
7919            }
7920        }
7921    }
7922
7923    /**
7924     * @param uri This uri must NOT contain an embedded userId.
7925     * @param userId The userId in which the uri is to be resolved.
7926     */
7927    @Override
7928    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7929        enforceNotIsolatedCaller("releasePersistableUriPermission");
7930
7931        Preconditions.checkFlagsArgument(modeFlags,
7932                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7933
7934        synchronized (this) {
7935            final int callingUid = Binder.getCallingUid();
7936            boolean persistChanged = false;
7937
7938            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7939                    new GrantUri(userId, uri, false));
7940            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7941                    new GrantUri(userId, uri, true));
7942            if (exactPerm == null && prefixPerm == null) {
7943                throw new SecurityException("No permission grants found for UID " + callingUid
7944                        + " and Uri " + uri.toSafeString());
7945            }
7946
7947            if (exactPerm != null) {
7948                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7949                removeUriPermissionIfNeededLocked(exactPerm);
7950            }
7951            if (prefixPerm != null) {
7952                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7953                removeUriPermissionIfNeededLocked(prefixPerm);
7954            }
7955
7956            if (persistChanged) {
7957                schedulePersistUriGrants();
7958            }
7959        }
7960    }
7961
7962    /**
7963     * Prune any older {@link UriPermission} for the given UID until outstanding
7964     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7965     *
7966     * @return if any mutations occured that require persisting.
7967     */
7968    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7969        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7970        if (perms == null) return false;
7971        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7972
7973        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7974        for (UriPermission perm : perms.values()) {
7975            if (perm.persistedModeFlags != 0) {
7976                persisted.add(perm);
7977            }
7978        }
7979
7980        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7981        if (trimCount <= 0) return false;
7982
7983        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7984        for (int i = 0; i < trimCount; i++) {
7985            final UriPermission perm = persisted.get(i);
7986
7987            if (DEBUG_URI_PERMISSION) {
7988                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7989            }
7990
7991            perm.releasePersistableModes(~0);
7992            removeUriPermissionIfNeededLocked(perm);
7993        }
7994
7995        return true;
7996    }
7997
7998    @Override
7999    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8000            String packageName, boolean incoming) {
8001        enforceNotIsolatedCaller("getPersistedUriPermissions");
8002        Preconditions.checkNotNull(packageName, "packageName");
8003
8004        final int callingUid = Binder.getCallingUid();
8005        final IPackageManager pm = AppGlobals.getPackageManager();
8006        try {
8007            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8008            if (packageUid != callingUid) {
8009                throw new SecurityException(
8010                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8011            }
8012        } catch (RemoteException e) {
8013            throw new SecurityException("Failed to verify package name ownership");
8014        }
8015
8016        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8017        synchronized (this) {
8018            if (incoming) {
8019                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8020                        callingUid);
8021                if (perms == null) {
8022                    Slog.w(TAG, "No permission grants found for " + packageName);
8023                } else {
8024                    for (UriPermission perm : perms.values()) {
8025                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8026                            result.add(perm.buildPersistedPublicApiObject());
8027                        }
8028                    }
8029                }
8030            } else {
8031                final int size = mGrantedUriPermissions.size();
8032                for (int i = 0; i < size; i++) {
8033                    final ArrayMap<GrantUri, UriPermission> perms =
8034                            mGrantedUriPermissions.valueAt(i);
8035                    for (UriPermission perm : perms.values()) {
8036                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8037                            result.add(perm.buildPersistedPublicApiObject());
8038                        }
8039                    }
8040                }
8041            }
8042        }
8043        return new ParceledListSlice<android.content.UriPermission>(result);
8044    }
8045
8046    @Override
8047    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8048        synchronized (this) {
8049            ProcessRecord app =
8050                who != null ? getRecordForAppLocked(who) : null;
8051            if (app == null) return;
8052
8053            Message msg = Message.obtain();
8054            msg.what = WAIT_FOR_DEBUGGER_MSG;
8055            msg.obj = app;
8056            msg.arg1 = waiting ? 1 : 0;
8057            mHandler.sendMessage(msg);
8058        }
8059    }
8060
8061    @Override
8062    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8063        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8064        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8065        outInfo.availMem = Process.getFreeMemory();
8066        outInfo.totalMem = Process.getTotalMemory();
8067        outInfo.threshold = homeAppMem;
8068        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8069        outInfo.hiddenAppThreshold = cachedAppMem;
8070        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8071                ProcessList.SERVICE_ADJ);
8072        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8073                ProcessList.VISIBLE_APP_ADJ);
8074        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8075                ProcessList.FOREGROUND_APP_ADJ);
8076    }
8077
8078    // =========================================================
8079    // TASK MANAGEMENT
8080    // =========================================================
8081
8082    @Override
8083    public List<IAppTask> getAppTasks(String callingPackage) {
8084        int callingUid = Binder.getCallingUid();
8085        long ident = Binder.clearCallingIdentity();
8086
8087        synchronized(this) {
8088            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8089            try {
8090                if (localLOGV) Slog.v(TAG, "getAppTasks");
8091
8092                final int N = mRecentTasks.size();
8093                for (int i = 0; i < N; i++) {
8094                    TaskRecord tr = mRecentTasks.get(i);
8095                    // Skip tasks that do not match the caller.  We don't need to verify
8096                    // callingPackage, because we are also limiting to callingUid and know
8097                    // that will limit to the correct security sandbox.
8098                    if (tr.effectiveUid != callingUid) {
8099                        continue;
8100                    }
8101                    Intent intent = tr.getBaseIntent();
8102                    if (intent == null ||
8103                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8104                        continue;
8105                    }
8106                    ActivityManager.RecentTaskInfo taskInfo =
8107                            createRecentTaskInfoFromTaskRecord(tr);
8108                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8109                    list.add(taskImpl);
8110                }
8111            } finally {
8112                Binder.restoreCallingIdentity(ident);
8113            }
8114            return list;
8115        }
8116    }
8117
8118    @Override
8119    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8120        final int callingUid = Binder.getCallingUid();
8121        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8122
8123        synchronized(this) {
8124            if (localLOGV) Slog.v(
8125                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8126
8127            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8128                    callingUid);
8129
8130            // TODO: Improve with MRU list from all ActivityStacks.
8131            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8132        }
8133
8134        return list;
8135    }
8136
8137    /**
8138     * Creates a new RecentTaskInfo from a TaskRecord.
8139     */
8140    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8141        // Update the task description to reflect any changes in the task stack
8142        tr.updateTaskDescription();
8143
8144        // Compose the recent task info
8145        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8146        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8147        rti.persistentId = tr.taskId;
8148        rti.baseIntent = new Intent(tr.getBaseIntent());
8149        rti.origActivity = tr.origActivity;
8150        rti.description = tr.lastDescription;
8151        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8152        rti.userId = tr.userId;
8153        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8154        rti.firstActiveTime = tr.firstActiveTime;
8155        rti.lastActiveTime = tr.lastActiveTime;
8156        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8157        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8158        return rti;
8159    }
8160
8161    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8162        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8163                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8164        if (!allowed) {
8165            if (checkPermission(android.Manifest.permission.GET_TASKS,
8166                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8167                // Temporary compatibility: some existing apps on the system image may
8168                // still be requesting the old permission and not switched to the new
8169                // one; if so, we'll still allow them full access.  This means we need
8170                // to see if they are holding the old permission and are a system app.
8171                try {
8172                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8173                        allowed = true;
8174                        Slog.w(TAG, caller + ": caller " + callingUid
8175                                + " is using old GET_TASKS but privileged; allowing");
8176                    }
8177                } catch (RemoteException e) {
8178                }
8179            }
8180        }
8181        if (!allowed) {
8182            Slog.w(TAG, caller + ": caller " + callingUid
8183                    + " does not hold GET_TASKS; limiting output");
8184        }
8185        return allowed;
8186    }
8187
8188    @Override
8189    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8190        final int callingUid = Binder.getCallingUid();
8191        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8192                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8193
8194        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8195        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8196        synchronized (this) {
8197            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8198                    callingUid);
8199            final boolean detailed = checkCallingPermission(
8200                    android.Manifest.permission.GET_DETAILED_TASKS)
8201                    == PackageManager.PERMISSION_GRANTED;
8202
8203            final int N = mRecentTasks.size();
8204            ArrayList<ActivityManager.RecentTaskInfo> res
8205                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8206                            maxNum < N ? maxNum : N);
8207
8208            final Set<Integer> includedUsers;
8209            if (includeProfiles) {
8210                includedUsers = getProfileIdsLocked(userId);
8211            } else {
8212                includedUsers = new HashSet<Integer>();
8213            }
8214            includedUsers.add(Integer.valueOf(userId));
8215
8216            for (int i=0; i<N && maxNum > 0; i++) {
8217                TaskRecord tr = mRecentTasks.get(i);
8218                // Only add calling user or related users recent tasks
8219                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8220                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8221                    continue;
8222                }
8223
8224                // Return the entry if desired by the caller.  We always return
8225                // the first entry, because callers always expect this to be the
8226                // foreground app.  We may filter others if the caller has
8227                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8228                // we should exclude the entry.
8229
8230                if (i == 0
8231                        || withExcluded
8232                        || (tr.intent == null)
8233                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8234                                == 0)) {
8235                    if (!allowed) {
8236                        // If the caller doesn't have the GET_TASKS permission, then only
8237                        // allow them to see a small subset of tasks -- their own and home.
8238                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8239                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8240                            continue;
8241                        }
8242                    }
8243                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8244                        if (tr.stack != null && tr.stack.isHomeStack()) {
8245                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8246                            continue;
8247                        }
8248                    }
8249                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8250                        // Don't include auto remove tasks that are finished or finishing.
8251                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8252                                + tr);
8253                        continue;
8254                    }
8255                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8256                            && !tr.isAvailable) {
8257                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8258                        continue;
8259                    }
8260
8261                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8262                    if (!detailed) {
8263                        rti.baseIntent.replaceExtras((Bundle)null);
8264                    }
8265
8266                    res.add(rti);
8267                    maxNum--;
8268                }
8269            }
8270            return res;
8271        }
8272    }
8273
8274    TaskRecord recentTaskForIdLocked(int id) {
8275        final int N = mRecentTasks.size();
8276            for (int i=0; i<N; i++) {
8277                TaskRecord tr = mRecentTasks.get(i);
8278                if (tr.taskId == id) {
8279                    return tr;
8280                }
8281            }
8282            return null;
8283    }
8284
8285    @Override
8286    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8287        synchronized (this) {
8288            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8289                    "getTaskThumbnail()");
8290            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8291            if (tr != null) {
8292                return tr.getTaskThumbnailLocked();
8293            }
8294        }
8295        return null;
8296    }
8297
8298    @Override
8299    public int addAppTask(IBinder activityToken, Intent intent,
8300            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8301        final int callingUid = Binder.getCallingUid();
8302        final long callingIdent = Binder.clearCallingIdentity();
8303
8304        try {
8305            synchronized (this) {
8306                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8307                if (r == null) {
8308                    throw new IllegalArgumentException("Activity does not exist; token="
8309                            + activityToken);
8310                }
8311                ComponentName comp = intent.getComponent();
8312                if (comp == null) {
8313                    throw new IllegalArgumentException("Intent " + intent
8314                            + " must specify explicit component");
8315                }
8316                if (thumbnail.getWidth() != mThumbnailWidth
8317                        || thumbnail.getHeight() != mThumbnailHeight) {
8318                    throw new IllegalArgumentException("Bad thumbnail size: got "
8319                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8320                            + mThumbnailWidth + "x" + mThumbnailHeight);
8321                }
8322                if (intent.getSelector() != null) {
8323                    intent.setSelector(null);
8324                }
8325                if (intent.getSourceBounds() != null) {
8326                    intent.setSourceBounds(null);
8327                }
8328                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8329                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8330                        // The caller has added this as an auto-remove task...  that makes no
8331                        // sense, so turn off auto-remove.
8332                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8333                    }
8334                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8335                    // Must be a new task.
8336                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8337                }
8338                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8339                    mLastAddedTaskActivity = null;
8340                }
8341                ActivityInfo ainfo = mLastAddedTaskActivity;
8342                if (ainfo == null) {
8343                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8344                            comp, 0, UserHandle.getUserId(callingUid));
8345                    if (ainfo.applicationInfo.uid != callingUid) {
8346                        throw new SecurityException(
8347                                "Can't add task for another application: target uid="
8348                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8349                    }
8350                }
8351
8352                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8353                        intent, description);
8354
8355                int trimIdx = trimRecentsForTaskLocked(task, false);
8356                if (trimIdx >= 0) {
8357                    // If this would have caused a trim, then we'll abort because that
8358                    // means it would be added at the end of the list but then just removed.
8359                    return INVALID_TASK_ID;
8360                }
8361
8362                final int N = mRecentTasks.size();
8363                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8364                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8365                    tr.removedFromRecents();
8366                }
8367
8368                task.inRecents = true;
8369                mRecentTasks.add(task);
8370                r.task.stack.addTask(task, false, false);
8371
8372                task.setLastThumbnail(thumbnail);
8373                task.freeLastThumbnail();
8374
8375                return task.taskId;
8376            }
8377        } finally {
8378            Binder.restoreCallingIdentity(callingIdent);
8379        }
8380    }
8381
8382    @Override
8383    public Point getAppTaskThumbnailSize() {
8384        synchronized (this) {
8385            return new Point(mThumbnailWidth,  mThumbnailHeight);
8386        }
8387    }
8388
8389    @Override
8390    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8391        synchronized (this) {
8392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8393            if (r != null) {
8394                r.setTaskDescription(td);
8395                r.task.updateTaskDescription();
8396            }
8397        }
8398    }
8399
8400    @Override
8401    public Bitmap getTaskDescriptionIcon(String filename) {
8402        if (!FileUtils.isValidExtFilename(filename)
8403                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8404            throw new IllegalArgumentException("Bad filename: " + filename);
8405        }
8406        return mTaskPersister.getTaskDescriptionIcon(filename);
8407    }
8408
8409    @Override
8410    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8411            throws RemoteException {
8412        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8413                opts.getCustomInPlaceResId() == 0) {
8414            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8415                    "with valid animation");
8416        }
8417        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8418        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8419                opts.getCustomInPlaceResId());
8420        mWindowManager.executeAppTransition();
8421    }
8422
8423    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8424        mRecentTasks.remove(tr);
8425        tr.removedFromRecents();
8426        ComponentName component = tr.getBaseIntent().getComponent();
8427        if (component == null) {
8428            Slog.w(TAG, "No component for base intent of task: " + tr);
8429            return;
8430        }
8431
8432        if (!killProcess) {
8433            return;
8434        }
8435
8436        // Determine if the process(es) for this task should be killed.
8437        final String pkg = component.getPackageName();
8438        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8439        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8440        for (int i = 0; i < pmap.size(); i++) {
8441
8442            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8443            for (int j = 0; j < uids.size(); j++) {
8444                ProcessRecord proc = uids.valueAt(j);
8445                if (proc.userId != tr.userId) {
8446                    // Don't kill process for a different user.
8447                    continue;
8448                }
8449                if (proc == mHomeProcess) {
8450                    // Don't kill the home process along with tasks from the same package.
8451                    continue;
8452                }
8453                if (!proc.pkgList.containsKey(pkg)) {
8454                    // Don't kill process that is not associated with this task.
8455                    continue;
8456                }
8457
8458                for (int k = 0; k < proc.activities.size(); k++) {
8459                    TaskRecord otherTask = proc.activities.get(k).task;
8460                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8461                        // Don't kill process(es) that has an activity in a different task that is
8462                        // also in recents.
8463                        return;
8464                    }
8465                }
8466
8467                // Add process to kill list.
8468                procsToKill.add(proc);
8469            }
8470        }
8471
8472        // Find any running services associated with this app and stop if needed.
8473        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8474
8475        // Kill the running processes.
8476        for (int i = 0; i < procsToKill.size(); i++) {
8477            ProcessRecord pr = procsToKill.get(i);
8478            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8479                pr.kill("remove task", true);
8480            } else {
8481                pr.waitingToKill = "remove task";
8482            }
8483        }
8484    }
8485
8486    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8487        // Remove all tasks with activities in the specified package from the list of recent tasks
8488        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8489            TaskRecord tr = mRecentTasks.get(i);
8490            if (tr.userId != userId) continue;
8491
8492            ComponentName cn = tr.intent.getComponent();
8493            if (cn != null && cn.getPackageName().equals(packageName)) {
8494                // If the package name matches, remove the task.
8495                removeTaskByIdLocked(tr.taskId, true);
8496            }
8497        }
8498    }
8499
8500    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8501        final IPackageManager pm = AppGlobals.getPackageManager();
8502        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8503
8504        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8505            TaskRecord tr = mRecentTasks.get(i);
8506            if (tr.userId != userId) continue;
8507
8508            ComponentName cn = tr.intent.getComponent();
8509            if (cn != null && cn.getPackageName().equals(packageName)) {
8510                // Skip if component still exists in the package.
8511                if (componentsKnownToExist.contains(cn)) continue;
8512
8513                try {
8514                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8515                    if (info != null) {
8516                        componentsKnownToExist.add(cn);
8517                    } else {
8518                        removeTaskByIdLocked(tr.taskId, false);
8519                    }
8520                } catch (RemoteException e) {
8521                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8522                }
8523            }
8524        }
8525    }
8526
8527    /**
8528     * Removes the task with the specified task id.
8529     *
8530     * @param taskId Identifier of the task to be removed.
8531     * @param killProcess Kill any process associated with the task if possible.
8532     * @return Returns true if the given task was found and removed.
8533     */
8534    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8535        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8536        if (tr != null) {
8537            tr.removeTaskActivitiesLocked();
8538            cleanUpRemovedTaskLocked(tr, killProcess);
8539            if (tr.isPersistable) {
8540                notifyTaskPersisterLocked(null, true);
8541            }
8542            return true;
8543        }
8544        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8545        return false;
8546    }
8547
8548    @Override
8549    public boolean removeTask(int taskId) {
8550        synchronized (this) {
8551            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8552                    "removeTask()");
8553            long ident = Binder.clearCallingIdentity();
8554            try {
8555                return removeTaskByIdLocked(taskId, true);
8556            } finally {
8557                Binder.restoreCallingIdentity(ident);
8558            }
8559        }
8560    }
8561
8562    /**
8563     * TODO: Add mController hook
8564     */
8565    @Override
8566    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8567        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8568                "moveTaskToFront()");
8569
8570        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8571        synchronized(this) {
8572            moveTaskToFrontLocked(taskId, flags, options);
8573        }
8574    }
8575
8576    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8577        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8578                Binder.getCallingUid(), -1, -1, "Task to front")) {
8579            ActivityOptions.abort(options);
8580            return;
8581        }
8582        final long origId = Binder.clearCallingIdentity();
8583        try {
8584            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8585            if (task == null) {
8586                Slog.d(TAG, "Could not find task for id: "+ taskId);
8587                return;
8588            }
8589            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8590                mStackSupervisor.showLockTaskToast();
8591                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8592                return;
8593            }
8594            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8595            if (prev != null && prev.isRecentsActivity()) {
8596                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8597            }
8598            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8599        } finally {
8600            Binder.restoreCallingIdentity(origId);
8601        }
8602        ActivityOptions.abort(options);
8603    }
8604
8605    @Override
8606    public void moveTaskToBack(int taskId) {
8607        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8608                "moveTaskToBack()");
8609
8610        synchronized(this) {
8611            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8612            if (tr != null) {
8613                if (tr == mStackSupervisor.mLockTaskModeTask) {
8614                    mStackSupervisor.showLockTaskToast();
8615                    return;
8616                }
8617                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8618                ActivityStack stack = tr.stack;
8619                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8620                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8621                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8622                        return;
8623                    }
8624                }
8625                final long origId = Binder.clearCallingIdentity();
8626                try {
8627                    stack.moveTaskToBackLocked(taskId);
8628                } finally {
8629                    Binder.restoreCallingIdentity(origId);
8630                }
8631            }
8632        }
8633    }
8634
8635    /**
8636     * Moves an activity, and all of the other activities within the same task, to the bottom
8637     * of the history stack.  The activity's order within the task is unchanged.
8638     *
8639     * @param token A reference to the activity we wish to move
8640     * @param nonRoot If false then this only works if the activity is the root
8641     *                of a task; if true it will work for any activity in a task.
8642     * @return Returns true if the move completed, false if not.
8643     */
8644    @Override
8645    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8646        enforceNotIsolatedCaller("moveActivityTaskToBack");
8647        synchronized(this) {
8648            final long origId = Binder.clearCallingIdentity();
8649            try {
8650                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8651                if (taskId >= 0) {
8652                    if ((mStackSupervisor.mLockTaskModeTask != null)
8653                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8654                        mStackSupervisor.showLockTaskToast();
8655                        return false;
8656                    }
8657                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8658                }
8659            } finally {
8660                Binder.restoreCallingIdentity(origId);
8661            }
8662        }
8663        return false;
8664    }
8665
8666    @Override
8667    public void moveTaskBackwards(int task) {
8668        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8669                "moveTaskBackwards()");
8670
8671        synchronized(this) {
8672            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8673                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8674                return;
8675            }
8676            final long origId = Binder.clearCallingIdentity();
8677            moveTaskBackwardsLocked(task);
8678            Binder.restoreCallingIdentity(origId);
8679        }
8680    }
8681
8682    private final void moveTaskBackwardsLocked(int task) {
8683        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8684    }
8685
8686    @Override
8687    public IBinder getHomeActivityToken() throws RemoteException {
8688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8689                "getHomeActivityToken()");
8690        synchronized (this) {
8691            return mStackSupervisor.getHomeActivityToken();
8692        }
8693    }
8694
8695    @Override
8696    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8697            IActivityContainerCallback callback) throws RemoteException {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "createActivityContainer()");
8700        synchronized (this) {
8701            if (parentActivityToken == null) {
8702                throw new IllegalArgumentException("parent token must not be null");
8703            }
8704            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8705            if (r == null) {
8706                return null;
8707            }
8708            if (callback == null) {
8709                throw new IllegalArgumentException("callback must not be null");
8710            }
8711            return mStackSupervisor.createActivityContainer(r, callback);
8712        }
8713    }
8714
8715    @Override
8716    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8718                "deleteActivityContainer()");
8719        synchronized (this) {
8720            mStackSupervisor.deleteActivityContainer(container);
8721        }
8722    }
8723
8724    @Override
8725    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8726        synchronized (this) {
8727            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8728            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8729                return stack.mActivityContainer.getDisplayId();
8730            }
8731            return Display.DEFAULT_DISPLAY;
8732        }
8733    }
8734
8735    @Override
8736    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8738                "moveTaskToStack()");
8739        if (stackId == HOME_STACK_ID) {
8740            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8741                    new RuntimeException("here").fillInStackTrace());
8742        }
8743        synchronized (this) {
8744            long ident = Binder.clearCallingIdentity();
8745            try {
8746                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8747                        + stackId + " toTop=" + toTop);
8748                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8749            } finally {
8750                Binder.restoreCallingIdentity(ident);
8751            }
8752        }
8753    }
8754
8755    @Override
8756    public void resizeStack(int stackBoxId, Rect bounds) {
8757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8758                "resizeStackBox()");
8759        long ident = Binder.clearCallingIdentity();
8760        try {
8761            mWindowManager.resizeStack(stackBoxId, bounds);
8762        } finally {
8763            Binder.restoreCallingIdentity(ident);
8764        }
8765    }
8766
8767    @Override
8768    public List<StackInfo> getAllStackInfos() {
8769        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8770                "getAllStackInfos()");
8771        long ident = Binder.clearCallingIdentity();
8772        try {
8773            synchronized (this) {
8774                return mStackSupervisor.getAllStackInfosLocked();
8775            }
8776        } finally {
8777            Binder.restoreCallingIdentity(ident);
8778        }
8779    }
8780
8781    @Override
8782    public StackInfo getStackInfo(int stackId) {
8783        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8784                "getStackInfo()");
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                return mStackSupervisor.getStackInfoLocked(stackId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793    }
8794
8795    @Override
8796    public boolean isInHomeStack(int taskId) {
8797        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8798                "getStackInfo()");
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8803                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8804            }
8805        } finally {
8806            Binder.restoreCallingIdentity(ident);
8807        }
8808    }
8809
8810    @Override
8811    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8812        synchronized(this) {
8813            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8814        }
8815    }
8816
8817    private boolean isLockTaskAuthorized(String pkg) {
8818        final DevicePolicyManager dpm = (DevicePolicyManager)
8819                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8820        try {
8821            int uid = mContext.getPackageManager().getPackageUid(pkg,
8822                    Binder.getCallingUserHandle().getIdentifier());
8823            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8824        } catch (NameNotFoundException e) {
8825            return false;
8826        }
8827    }
8828
8829    void startLockTaskMode(TaskRecord task) {
8830        final String pkg;
8831        synchronized (this) {
8832            pkg = task.intent.getComponent().getPackageName();
8833        }
8834        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8835        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8836            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8837                    StatusBarManagerInternal.class);
8838            if (statusBarManager != null) {
8839                statusBarManager.showScreenPinningRequest();
8840            }
8841            return;
8842        }
8843        long ident = Binder.clearCallingIdentity();
8844        try {
8845            synchronized (this) {
8846                // Since we lost lock on task, make sure it is still there.
8847                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8848                if (task != null) {
8849                    if (!isSystemInitiated
8850                            && ((mStackSupervisor.getFocusedStack() == null)
8851                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8852                        throw new IllegalArgumentException("Invalid task, not in foreground");
8853                    }
8854                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8855                            "startLockTask");
8856                }
8857            }
8858        } finally {
8859            Binder.restoreCallingIdentity(ident);
8860        }
8861    }
8862
8863    @Override
8864    public void startLockTaskMode(int taskId) {
8865        final TaskRecord task;
8866        long ident = Binder.clearCallingIdentity();
8867        try {
8868            synchronized (this) {
8869                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8870            }
8871        } finally {
8872            Binder.restoreCallingIdentity(ident);
8873        }
8874        if (task != null) {
8875            startLockTaskMode(task);
8876        }
8877    }
8878
8879    @Override
8880    public void startLockTaskMode(IBinder token) {
8881        final TaskRecord task;
8882        long ident = Binder.clearCallingIdentity();
8883        try {
8884            synchronized (this) {
8885                final ActivityRecord r = ActivityRecord.forToken(token);
8886                if (r == null) {
8887                    return;
8888                }
8889                task = r.task;
8890            }
8891        } finally {
8892            Binder.restoreCallingIdentity(ident);
8893        }
8894        if (task != null) {
8895            startLockTaskMode(task);
8896        }
8897    }
8898
8899    @Override
8900    public void startLockTaskModeOnCurrent() throws RemoteException {
8901        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8902                "startLockTaskModeOnCurrent");
8903        long ident = Binder.clearCallingIdentity();
8904        try {
8905            ActivityRecord r = null;
8906            synchronized (this) {
8907                r = mStackSupervisor.topRunningActivityLocked();
8908            }
8909            startLockTaskMode(r.task);
8910        } finally {
8911            Binder.restoreCallingIdentity(ident);
8912        }
8913    }
8914
8915    @Override
8916    public void stopLockTaskMode() {
8917        // Verify that the user matches the package of the intent for the TaskRecord
8918        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8919        // and stopLockTaskMode.
8920        final int callingUid = Binder.getCallingUid();
8921        if (callingUid != Process.SYSTEM_UID) {
8922            try {
8923                String pkg =
8924                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8925                int uid = mContext.getPackageManager().getPackageUid(pkg,
8926                        Binder.getCallingUserHandle().getIdentifier());
8927                if (uid != callingUid) {
8928                    throw new SecurityException("Invalid uid, expected " + uid);
8929                }
8930            } catch (NameNotFoundException e) {
8931                Log.d(TAG, "stopLockTaskMode " + e);
8932                return;
8933            }
8934        }
8935        long ident = Binder.clearCallingIdentity();
8936        try {
8937            Log.d(TAG, "stopLockTaskMode");
8938            // Stop lock task
8939            synchronized (this) {
8940                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8941            }
8942        } finally {
8943            Binder.restoreCallingIdentity(ident);
8944        }
8945    }
8946
8947    @Override
8948    public void stopLockTaskModeOnCurrent() throws RemoteException {
8949        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8950                "stopLockTaskModeOnCurrent");
8951        long ident = Binder.clearCallingIdentity();
8952        try {
8953            stopLockTaskMode();
8954        } finally {
8955            Binder.restoreCallingIdentity(ident);
8956        }
8957    }
8958
8959    @Override
8960    public boolean isInLockTaskMode() {
8961        synchronized (this) {
8962            return mStackSupervisor.isInLockTaskMode();
8963        }
8964    }
8965
8966    // =========================================================
8967    // CONTENT PROVIDERS
8968    // =========================================================
8969
8970    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8971        List<ProviderInfo> providers = null;
8972        try {
8973            providers = AppGlobals.getPackageManager().
8974                queryContentProviders(app.processName, app.uid,
8975                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8976        } catch (RemoteException ex) {
8977        }
8978        if (DEBUG_MU)
8979            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8980        int userId = app.userId;
8981        if (providers != null) {
8982            int N = providers.size();
8983            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8984            for (int i=0; i<N; i++) {
8985                ProviderInfo cpi =
8986                    (ProviderInfo)providers.get(i);
8987                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8988                        cpi.name, cpi.flags);
8989                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8990                    // This is a singleton provider, but a user besides the
8991                    // default user is asking to initialize a process it runs
8992                    // in...  well, no, it doesn't actually run in this process,
8993                    // it runs in the process of the default user.  Get rid of it.
8994                    providers.remove(i);
8995                    N--;
8996                    i--;
8997                    continue;
8998                }
8999
9000                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9001                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9002                if (cpr == null) {
9003                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9004                    mProviderMap.putProviderByClass(comp, cpr);
9005                }
9006                if (DEBUG_MU)
9007                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9008                app.pubProviders.put(cpi.name, cpr);
9009                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9010                    // Don't add this if it is a platform component that is marked
9011                    // to run in multiple processes, because this is actually
9012                    // part of the framework so doesn't make sense to track as a
9013                    // separate apk in the process.
9014                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9015                            mProcessStats);
9016                }
9017                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9018            }
9019        }
9020        return providers;
9021    }
9022
9023    /**
9024     * Check if {@link ProcessRecord} has a possible chance at accessing the
9025     * given {@link ProviderInfo}. Final permission checking is always done
9026     * in {@link ContentProvider}.
9027     */
9028    private final String checkContentProviderPermissionLocked(
9029            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9030        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9031        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9032        boolean checkedGrants = false;
9033        if (checkUser) {
9034            // Looking for cross-user grants before enforcing the typical cross-users permissions
9035            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9036            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9037                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9038                    return null;
9039                }
9040                checkedGrants = true;
9041            }
9042            userId = handleIncomingUser(callingPid, callingUid, userId,
9043                    false, ALLOW_NON_FULL,
9044                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9045            if (userId != tmpTargetUserId) {
9046                // When we actually went to determine the final targer user ID, this ended
9047                // up different than our initial check for the authority.  This is because
9048                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9049                // SELF.  So we need to re-check the grants again.
9050                checkedGrants = false;
9051            }
9052        }
9053        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9054                cpi.applicationInfo.uid, cpi.exported)
9055                == PackageManager.PERMISSION_GRANTED) {
9056            return null;
9057        }
9058        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9059                cpi.applicationInfo.uid, cpi.exported)
9060                == PackageManager.PERMISSION_GRANTED) {
9061            return null;
9062        }
9063
9064        PathPermission[] pps = cpi.pathPermissions;
9065        if (pps != null) {
9066            int i = pps.length;
9067            while (i > 0) {
9068                i--;
9069                PathPermission pp = pps[i];
9070                String pprperm = pp.getReadPermission();
9071                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9072                        cpi.applicationInfo.uid, cpi.exported)
9073                        == PackageManager.PERMISSION_GRANTED) {
9074                    return null;
9075                }
9076                String ppwperm = pp.getWritePermission();
9077                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9078                        cpi.applicationInfo.uid, cpi.exported)
9079                        == PackageManager.PERMISSION_GRANTED) {
9080                    return null;
9081                }
9082            }
9083        }
9084        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9085            return null;
9086        }
9087
9088        String msg;
9089        if (!cpi.exported) {
9090            msg = "Permission Denial: opening provider " + cpi.name
9091                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9092                    + ", uid=" + callingUid + ") that is not exported from uid "
9093                    + cpi.applicationInfo.uid;
9094        } else {
9095            msg = "Permission Denial: opening provider " + cpi.name
9096                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9097                    + ", uid=" + callingUid + ") requires "
9098                    + cpi.readPermission + " or " + cpi.writePermission;
9099        }
9100        Slog.w(TAG, msg);
9101        return msg;
9102    }
9103
9104    /**
9105     * Returns if the ContentProvider has granted a uri to callingUid
9106     */
9107    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9108        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9109        if (perms != null) {
9110            for (int i=perms.size()-1; i>=0; i--) {
9111                GrantUri grantUri = perms.keyAt(i);
9112                if (grantUri.sourceUserId == userId || !checkUser) {
9113                    if (matchesProvider(grantUri.uri, cpi)) {
9114                        return true;
9115                    }
9116                }
9117            }
9118        }
9119        return false;
9120    }
9121
9122    /**
9123     * Returns true if the uri authority is one of the authorities specified in the provider.
9124     */
9125    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9126        String uriAuth = uri.getAuthority();
9127        String cpiAuth = cpi.authority;
9128        if (cpiAuth.indexOf(';') == -1) {
9129            return cpiAuth.equals(uriAuth);
9130        }
9131        String[] cpiAuths = cpiAuth.split(";");
9132        int length = cpiAuths.length;
9133        for (int i = 0; i < length; i++) {
9134            if (cpiAuths[i].equals(uriAuth)) return true;
9135        }
9136        return false;
9137    }
9138
9139    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9140            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9141        if (r != null) {
9142            for (int i=0; i<r.conProviders.size(); i++) {
9143                ContentProviderConnection conn = r.conProviders.get(i);
9144                if (conn.provider == cpr) {
9145                    if (DEBUG_PROVIDER) Slog.v(TAG,
9146                            "Adding provider requested by "
9147                            + r.processName + " from process "
9148                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9149                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9150                    if (stable) {
9151                        conn.stableCount++;
9152                        conn.numStableIncs++;
9153                    } else {
9154                        conn.unstableCount++;
9155                        conn.numUnstableIncs++;
9156                    }
9157                    return conn;
9158                }
9159            }
9160            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9161            if (stable) {
9162                conn.stableCount = 1;
9163                conn.numStableIncs = 1;
9164            } else {
9165                conn.unstableCount = 1;
9166                conn.numUnstableIncs = 1;
9167            }
9168            cpr.connections.add(conn);
9169            r.conProviders.add(conn);
9170            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9171            return conn;
9172        }
9173        cpr.addExternalProcessHandleLocked(externalProcessToken);
9174        return null;
9175    }
9176
9177    boolean decProviderCountLocked(ContentProviderConnection conn,
9178            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9179        if (conn != null) {
9180            cpr = conn.provider;
9181            if (DEBUG_PROVIDER) Slog.v(TAG,
9182                    "Removing provider requested by "
9183                    + conn.client.processName + " from process "
9184                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9185                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9186            if (stable) {
9187                conn.stableCount--;
9188            } else {
9189                conn.unstableCount--;
9190            }
9191            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9192                cpr.connections.remove(conn);
9193                conn.client.conProviders.remove(conn);
9194                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9195                return true;
9196            }
9197            return false;
9198        }
9199        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9200        return false;
9201    }
9202
9203    private void checkTime(long startTime, String where) {
9204        long now = SystemClock.elapsedRealtime();
9205        if ((now-startTime) > 1000) {
9206            // If we are taking more than a second, log about it.
9207            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9208        }
9209    }
9210
9211    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9212            String name, IBinder token, boolean stable, int userId) {
9213        ContentProviderRecord cpr;
9214        ContentProviderConnection conn = null;
9215        ProviderInfo cpi = null;
9216
9217        synchronized(this) {
9218            long startTime = SystemClock.elapsedRealtime();
9219
9220            ProcessRecord r = null;
9221            if (caller != null) {
9222                r = getRecordForAppLocked(caller);
9223                if (r == null) {
9224                    throw new SecurityException(
9225                            "Unable to find app for caller " + caller
9226                          + " (pid=" + Binder.getCallingPid()
9227                          + ") when getting content provider " + name);
9228                }
9229            }
9230
9231            boolean checkCrossUser = true;
9232
9233            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9234
9235            // First check if this content provider has been published...
9236            cpr = mProviderMap.getProviderByName(name, userId);
9237            // If that didn't work, check if it exists for user 0 and then
9238            // verify that it's a singleton provider before using it.
9239            if (cpr == null && userId != UserHandle.USER_OWNER) {
9240                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9241                if (cpr != null) {
9242                    cpi = cpr.info;
9243                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9244                            cpi.name, cpi.flags)
9245                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9246                        userId = UserHandle.USER_OWNER;
9247                        checkCrossUser = false;
9248                    } else {
9249                        cpr = null;
9250                        cpi = null;
9251                    }
9252                }
9253            }
9254
9255            boolean providerRunning = cpr != null;
9256            if (providerRunning) {
9257                cpi = cpr.info;
9258                String msg;
9259                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9260                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9261                        != null) {
9262                    throw new SecurityException(msg);
9263                }
9264                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9265
9266                if (r != null && cpr.canRunHere(r)) {
9267                    // This provider has been published or is in the process
9268                    // of being published...  but it is also allowed to run
9269                    // in the caller's process, so don't make a connection
9270                    // and just let the caller instantiate its own instance.
9271                    ContentProviderHolder holder = cpr.newHolder(null);
9272                    // don't give caller the provider object, it needs
9273                    // to make its own.
9274                    holder.provider = null;
9275                    return holder;
9276                }
9277
9278                final long origId = Binder.clearCallingIdentity();
9279
9280                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9281
9282                // In this case the provider instance already exists, so we can
9283                // return it right away.
9284                conn = incProviderCountLocked(r, cpr, token, stable);
9285                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9286                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9287                        // If this is a perceptible app accessing the provider,
9288                        // make sure to count it as being accessed and thus
9289                        // back up on the LRU list.  This is good because
9290                        // content providers are often expensive to start.
9291                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9292                        updateLruProcessLocked(cpr.proc, false, null);
9293                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9294                    }
9295                }
9296
9297                if (cpr.proc != null) {
9298                    if (false) {
9299                        if (cpr.name.flattenToShortString().equals(
9300                                "com.android.providers.calendar/.CalendarProvider2")) {
9301                            Slog.v(TAG, "****************** KILLING "
9302                                + cpr.name.flattenToShortString());
9303                            Process.killProcess(cpr.proc.pid);
9304                        }
9305                    }
9306                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9307                    boolean success = updateOomAdjLocked(cpr.proc);
9308                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9309                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9310                    // NOTE: there is still a race here where a signal could be
9311                    // pending on the process even though we managed to update its
9312                    // adj level.  Not sure what to do about this, but at least
9313                    // the race is now smaller.
9314                    if (!success) {
9315                        // Uh oh...  it looks like the provider's process
9316                        // has been killed on us.  We need to wait for a new
9317                        // process to be started, and make sure its death
9318                        // doesn't kill our process.
9319                        Slog.i(TAG,
9320                                "Existing provider " + cpr.name.flattenToShortString()
9321                                + " is crashing; detaching " + r);
9322                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9323                        checkTime(startTime, "getContentProviderImpl: before appDied");
9324                        appDiedLocked(cpr.proc);
9325                        checkTime(startTime, "getContentProviderImpl: after appDied");
9326                        if (!lastRef) {
9327                            // This wasn't the last ref our process had on
9328                            // the provider...  we have now been killed, bail.
9329                            return null;
9330                        }
9331                        providerRunning = false;
9332                        conn = null;
9333                    }
9334                }
9335
9336                Binder.restoreCallingIdentity(origId);
9337            }
9338
9339            boolean singleton;
9340            if (!providerRunning) {
9341                try {
9342                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9343                    cpi = AppGlobals.getPackageManager().
9344                        resolveContentProvider(name,
9345                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9346                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9347                } catch (RemoteException ex) {
9348                }
9349                if (cpi == null) {
9350                    return null;
9351                }
9352                // If the provider is a singleton AND
9353                // (it's a call within the same user || the provider is a
9354                // privileged app)
9355                // Then allow connecting to the singleton provider
9356                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9357                        cpi.name, cpi.flags)
9358                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9359                if (singleton) {
9360                    userId = UserHandle.USER_OWNER;
9361                }
9362                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9363                checkTime(startTime, "getContentProviderImpl: got app info for user");
9364
9365                String msg;
9366                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9367                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9368                        != null) {
9369                    throw new SecurityException(msg);
9370                }
9371                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9372
9373                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9374                        && !cpi.processName.equals("system")) {
9375                    // If this content provider does not run in the system
9376                    // process, and the system is not yet ready to run other
9377                    // processes, then fail fast instead of hanging.
9378                    throw new IllegalArgumentException(
9379                            "Attempt to launch content provider before system ready");
9380                }
9381
9382                // Make sure that the user who owns this provider is running.  If not,
9383                // we don't want to allow it to run.
9384                if (!isUserRunningLocked(userId, false)) {
9385                    Slog.w(TAG, "Unable to launch app "
9386                            + cpi.applicationInfo.packageName + "/"
9387                            + cpi.applicationInfo.uid + " for provider "
9388                            + name + ": user " + userId + " is stopped");
9389                    return null;
9390                }
9391
9392                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9393                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9394                cpr = mProviderMap.getProviderByClass(comp, userId);
9395                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9396                final boolean firstClass = cpr == null;
9397                if (firstClass) {
9398                    final long ident = Binder.clearCallingIdentity();
9399                    try {
9400                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9401                        ApplicationInfo ai =
9402                            AppGlobals.getPackageManager().
9403                                getApplicationInfo(
9404                                        cpi.applicationInfo.packageName,
9405                                        STOCK_PM_FLAGS, userId);
9406                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9407                        if (ai == null) {
9408                            Slog.w(TAG, "No package info for content provider "
9409                                    + cpi.name);
9410                            return null;
9411                        }
9412                        ai = getAppInfoForUser(ai, userId);
9413                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9414                    } catch (RemoteException ex) {
9415                        // pm is in same process, this will never happen.
9416                    } finally {
9417                        Binder.restoreCallingIdentity(ident);
9418                    }
9419                }
9420
9421                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9422
9423                if (r != null && cpr.canRunHere(r)) {
9424                    // If this is a multiprocess provider, then just return its
9425                    // info and allow the caller to instantiate it.  Only do
9426                    // this if the provider is the same user as the caller's
9427                    // process, or can run as root (so can be in any process).
9428                    return cpr.newHolder(null);
9429                }
9430
9431                if (DEBUG_PROVIDER) {
9432                    RuntimeException e = new RuntimeException("here");
9433                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9434                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9435                }
9436
9437                // This is single process, and our app is now connecting to it.
9438                // See if we are already in the process of launching this
9439                // provider.
9440                final int N = mLaunchingProviders.size();
9441                int i;
9442                for (i=0; i<N; i++) {
9443                    if (mLaunchingProviders.get(i) == cpr) {
9444                        break;
9445                    }
9446                }
9447
9448                // If the provider is not already being launched, then get it
9449                // started.
9450                if (i >= N) {
9451                    final long origId = Binder.clearCallingIdentity();
9452
9453                    try {
9454                        // Content provider is now in use, its package can't be stopped.
9455                        try {
9456                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9457                            AppGlobals.getPackageManager().setPackageStoppedState(
9458                                    cpr.appInfo.packageName, false, userId);
9459                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9460                        } catch (RemoteException e) {
9461                        } catch (IllegalArgumentException e) {
9462                            Slog.w(TAG, "Failed trying to unstop package "
9463                                    + cpr.appInfo.packageName + ": " + e);
9464                        }
9465
9466                        // Use existing process if already started
9467                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9468                        ProcessRecord proc = getProcessRecordLocked(
9469                                cpi.processName, cpr.appInfo.uid, false);
9470                        if (proc != null && proc.thread != null) {
9471                            if (DEBUG_PROVIDER) {
9472                                Slog.d(TAG, "Installing in existing process " + proc);
9473                            }
9474                            if (!proc.pubProviders.containsKey(cpi.name)) {
9475                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9476                                proc.pubProviders.put(cpi.name, cpr);
9477                                try {
9478                                    proc.thread.scheduleInstallProvider(cpi);
9479                                } catch (RemoteException e) {
9480                                }
9481                            }
9482                        } else {
9483                            checkTime(startTime, "getContentProviderImpl: before start process");
9484                            proc = startProcessLocked(cpi.processName,
9485                                    cpr.appInfo, false, 0, "content provider",
9486                                    new ComponentName(cpi.applicationInfo.packageName,
9487                                            cpi.name), false, false, false);
9488                            checkTime(startTime, "getContentProviderImpl: after start process");
9489                            if (proc == null) {
9490                                Slog.w(TAG, "Unable to launch app "
9491                                        + cpi.applicationInfo.packageName + "/"
9492                                        + cpi.applicationInfo.uid + " for provider "
9493                                        + name + ": process is bad");
9494                                return null;
9495                            }
9496                        }
9497                        cpr.launchingApp = proc;
9498                        mLaunchingProviders.add(cpr);
9499                    } finally {
9500                        Binder.restoreCallingIdentity(origId);
9501                    }
9502                }
9503
9504                checkTime(startTime, "getContentProviderImpl: updating data structures");
9505
9506                // Make sure the provider is published (the same provider class
9507                // may be published under multiple names).
9508                if (firstClass) {
9509                    mProviderMap.putProviderByClass(comp, cpr);
9510                }
9511
9512                mProviderMap.putProviderByName(name, cpr);
9513                conn = incProviderCountLocked(r, cpr, token, stable);
9514                if (conn != null) {
9515                    conn.waiting = true;
9516                }
9517            }
9518            checkTime(startTime, "getContentProviderImpl: done!");
9519        }
9520
9521        // Wait for the provider to be published...
9522        synchronized (cpr) {
9523            while (cpr.provider == null) {
9524                if (cpr.launchingApp == null) {
9525                    Slog.w(TAG, "Unable to launch app "
9526                            + cpi.applicationInfo.packageName + "/"
9527                            + cpi.applicationInfo.uid + " for provider "
9528                            + name + ": launching app became null");
9529                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9530                            UserHandle.getUserId(cpi.applicationInfo.uid),
9531                            cpi.applicationInfo.packageName,
9532                            cpi.applicationInfo.uid, name);
9533                    return null;
9534                }
9535                try {
9536                    if (DEBUG_MU) {
9537                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9538                                + cpr.launchingApp);
9539                    }
9540                    if (conn != null) {
9541                        conn.waiting = true;
9542                    }
9543                    cpr.wait();
9544                } catch (InterruptedException ex) {
9545                } finally {
9546                    if (conn != null) {
9547                        conn.waiting = false;
9548                    }
9549                }
9550            }
9551        }
9552        return cpr != null ? cpr.newHolder(conn) : null;
9553    }
9554
9555    @Override
9556    public final ContentProviderHolder getContentProvider(
9557            IApplicationThread caller, String name, int userId, boolean stable) {
9558        enforceNotIsolatedCaller("getContentProvider");
9559        if (caller == null) {
9560            String msg = "null IApplicationThread when getting content provider "
9561                    + name;
9562            Slog.w(TAG, msg);
9563            throw new SecurityException(msg);
9564        }
9565        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9566        // with cross-user grant.
9567        return getContentProviderImpl(caller, name, null, stable, userId);
9568    }
9569
9570    public ContentProviderHolder getContentProviderExternal(
9571            String name, int userId, IBinder token) {
9572        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9573            "Do not have permission in call getContentProviderExternal()");
9574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9575                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9576        return getContentProviderExternalUnchecked(name, token, userId);
9577    }
9578
9579    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9580            IBinder token, int userId) {
9581        return getContentProviderImpl(null, name, token, true, userId);
9582    }
9583
9584    /**
9585     * Drop a content provider from a ProcessRecord's bookkeeping
9586     */
9587    public void removeContentProvider(IBinder connection, boolean stable) {
9588        enforceNotIsolatedCaller("removeContentProvider");
9589        long ident = Binder.clearCallingIdentity();
9590        try {
9591            synchronized (this) {
9592                ContentProviderConnection conn;
9593                try {
9594                    conn = (ContentProviderConnection)connection;
9595                } catch (ClassCastException e) {
9596                    String msg ="removeContentProvider: " + connection
9597                            + " not a ContentProviderConnection";
9598                    Slog.w(TAG, msg);
9599                    throw new IllegalArgumentException(msg);
9600                }
9601                if (conn == null) {
9602                    throw new NullPointerException("connection is null");
9603                }
9604                if (decProviderCountLocked(conn, null, null, stable)) {
9605                    updateOomAdjLocked();
9606                }
9607            }
9608        } finally {
9609            Binder.restoreCallingIdentity(ident);
9610        }
9611    }
9612
9613    public void removeContentProviderExternal(String name, IBinder token) {
9614        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9615            "Do not have permission in call removeContentProviderExternal()");
9616        int userId = UserHandle.getCallingUserId();
9617        long ident = Binder.clearCallingIdentity();
9618        try {
9619            removeContentProviderExternalUnchecked(name, token, userId);
9620        } finally {
9621            Binder.restoreCallingIdentity(ident);
9622        }
9623    }
9624
9625    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9626        synchronized (this) {
9627            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9628            if(cpr == null) {
9629                //remove from mProvidersByClass
9630                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9631                return;
9632            }
9633
9634            //update content provider record entry info
9635            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9636            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9637            if (localCpr.hasExternalProcessHandles()) {
9638                if (localCpr.removeExternalProcessHandleLocked(token)) {
9639                    updateOomAdjLocked();
9640                } else {
9641                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9642                            + " with no external reference for token: "
9643                            + token + ".");
9644                }
9645            } else {
9646                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9647                        + " with no external references.");
9648            }
9649        }
9650    }
9651
9652    public final void publishContentProviders(IApplicationThread caller,
9653            List<ContentProviderHolder> providers) {
9654        if (providers == null) {
9655            return;
9656        }
9657
9658        enforceNotIsolatedCaller("publishContentProviders");
9659        synchronized (this) {
9660            final ProcessRecord r = getRecordForAppLocked(caller);
9661            if (DEBUG_MU)
9662                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9663            if (r == null) {
9664                throw new SecurityException(
9665                        "Unable to find app for caller " + caller
9666                      + " (pid=" + Binder.getCallingPid()
9667                      + ") when publishing content providers");
9668            }
9669
9670            final long origId = Binder.clearCallingIdentity();
9671
9672            final int N = providers.size();
9673            for (int i=0; i<N; i++) {
9674                ContentProviderHolder src = providers.get(i);
9675                if (src == null || src.info == null || src.provider == null) {
9676                    continue;
9677                }
9678                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9679                if (DEBUG_MU)
9680                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9681                if (dst != null) {
9682                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9683                    mProviderMap.putProviderByClass(comp, dst);
9684                    String names[] = dst.info.authority.split(";");
9685                    for (int j = 0; j < names.length; j++) {
9686                        mProviderMap.putProviderByName(names[j], dst);
9687                    }
9688
9689                    int NL = mLaunchingProviders.size();
9690                    int j;
9691                    for (j=0; j<NL; j++) {
9692                        if (mLaunchingProviders.get(j) == dst) {
9693                            mLaunchingProviders.remove(j);
9694                            j--;
9695                            NL--;
9696                        }
9697                    }
9698                    synchronized (dst) {
9699                        dst.provider = src.provider;
9700                        dst.proc = r;
9701                        dst.notifyAll();
9702                    }
9703                    updateOomAdjLocked(r);
9704                }
9705            }
9706
9707            Binder.restoreCallingIdentity(origId);
9708        }
9709    }
9710
9711    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9712        ContentProviderConnection conn;
9713        try {
9714            conn = (ContentProviderConnection)connection;
9715        } catch (ClassCastException e) {
9716            String msg ="refContentProvider: " + connection
9717                    + " not a ContentProviderConnection";
9718            Slog.w(TAG, msg);
9719            throw new IllegalArgumentException(msg);
9720        }
9721        if (conn == null) {
9722            throw new NullPointerException("connection is null");
9723        }
9724
9725        synchronized (this) {
9726            if (stable > 0) {
9727                conn.numStableIncs += stable;
9728            }
9729            stable = conn.stableCount + stable;
9730            if (stable < 0) {
9731                throw new IllegalStateException("stableCount < 0: " + stable);
9732            }
9733
9734            if (unstable > 0) {
9735                conn.numUnstableIncs += unstable;
9736            }
9737            unstable = conn.unstableCount + unstable;
9738            if (unstable < 0) {
9739                throw new IllegalStateException("unstableCount < 0: " + unstable);
9740            }
9741
9742            if ((stable+unstable) <= 0) {
9743                throw new IllegalStateException("ref counts can't go to zero here: stable="
9744                        + stable + " unstable=" + unstable);
9745            }
9746            conn.stableCount = stable;
9747            conn.unstableCount = unstable;
9748            return !conn.dead;
9749        }
9750    }
9751
9752    public void unstableProviderDied(IBinder connection) {
9753        ContentProviderConnection conn;
9754        try {
9755            conn = (ContentProviderConnection)connection;
9756        } catch (ClassCastException e) {
9757            String msg ="refContentProvider: " + connection
9758                    + " not a ContentProviderConnection";
9759            Slog.w(TAG, msg);
9760            throw new IllegalArgumentException(msg);
9761        }
9762        if (conn == null) {
9763            throw new NullPointerException("connection is null");
9764        }
9765
9766        // Safely retrieve the content provider associated with the connection.
9767        IContentProvider provider;
9768        synchronized (this) {
9769            provider = conn.provider.provider;
9770        }
9771
9772        if (provider == null) {
9773            // Um, yeah, we're way ahead of you.
9774            return;
9775        }
9776
9777        // Make sure the caller is being honest with us.
9778        if (provider.asBinder().pingBinder()) {
9779            // Er, no, still looks good to us.
9780            synchronized (this) {
9781                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9782                        + " says " + conn + " died, but we don't agree");
9783                return;
9784            }
9785        }
9786
9787        // Well look at that!  It's dead!
9788        synchronized (this) {
9789            if (conn.provider.provider != provider) {
9790                // But something changed...  good enough.
9791                return;
9792            }
9793
9794            ProcessRecord proc = conn.provider.proc;
9795            if (proc == null || proc.thread == null) {
9796                // Seems like the process is already cleaned up.
9797                return;
9798            }
9799
9800            // As far as we're concerned, this is just like receiving a
9801            // death notification...  just a bit prematurely.
9802            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9803                    + ") early provider death");
9804            final long ident = Binder.clearCallingIdentity();
9805            try {
9806                appDiedLocked(proc);
9807            } finally {
9808                Binder.restoreCallingIdentity(ident);
9809            }
9810        }
9811    }
9812
9813    @Override
9814    public void appNotRespondingViaProvider(IBinder connection) {
9815        enforceCallingPermission(
9816                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9817
9818        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9819        if (conn == null) {
9820            Slog.w(TAG, "ContentProviderConnection is null");
9821            return;
9822        }
9823
9824        final ProcessRecord host = conn.provider.proc;
9825        if (host == null) {
9826            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9827            return;
9828        }
9829
9830        final long token = Binder.clearCallingIdentity();
9831        try {
9832            appNotResponding(host, null, null, false, "ContentProvider not responding");
9833        } finally {
9834            Binder.restoreCallingIdentity(token);
9835        }
9836    }
9837
9838    public final void installSystemProviders() {
9839        List<ProviderInfo> providers;
9840        synchronized (this) {
9841            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9842            providers = generateApplicationProvidersLocked(app);
9843            if (providers != null) {
9844                for (int i=providers.size()-1; i>=0; i--) {
9845                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9846                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9847                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9848                                + ": not system .apk");
9849                        providers.remove(i);
9850                    }
9851                }
9852            }
9853        }
9854        if (providers != null) {
9855            mSystemThread.installSystemProviders(providers);
9856        }
9857
9858        mCoreSettingsObserver = new CoreSettingsObserver(this);
9859
9860        //mUsageStatsService.monitorPackages();
9861    }
9862
9863    /**
9864     * Allows apps to retrieve the MIME type of a URI.
9865     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9866     * users, then it does not need permission to access the ContentProvider.
9867     * Either, it needs cross-user uri grants.
9868     *
9869     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9870     *
9871     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9872     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9873     */
9874    public String getProviderMimeType(Uri uri, int userId) {
9875        enforceNotIsolatedCaller("getProviderMimeType");
9876        final String name = uri.getAuthority();
9877        int callingUid = Binder.getCallingUid();
9878        int callingPid = Binder.getCallingPid();
9879        long ident = 0;
9880        boolean clearedIdentity = false;
9881        userId = unsafeConvertIncomingUser(userId);
9882        if (canClearIdentity(callingPid, callingUid, userId)) {
9883            clearedIdentity = true;
9884            ident = Binder.clearCallingIdentity();
9885        }
9886        ContentProviderHolder holder = null;
9887        try {
9888            holder = getContentProviderExternalUnchecked(name, null, userId);
9889            if (holder != null) {
9890                return holder.provider.getType(uri);
9891            }
9892        } catch (RemoteException e) {
9893            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9894            return null;
9895        } finally {
9896            // We need to clear the identity to call removeContentProviderExternalUnchecked
9897            if (!clearedIdentity) {
9898                ident = Binder.clearCallingIdentity();
9899            }
9900            try {
9901                if (holder != null) {
9902                    removeContentProviderExternalUnchecked(name, null, userId);
9903                }
9904            } finally {
9905                Binder.restoreCallingIdentity(ident);
9906            }
9907        }
9908
9909        return null;
9910    }
9911
9912    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9913        if (UserHandle.getUserId(callingUid) == userId) {
9914            return true;
9915        }
9916        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9917                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9918                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9919                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9920                return true;
9921        }
9922        return false;
9923    }
9924
9925    // =========================================================
9926    // GLOBAL MANAGEMENT
9927    // =========================================================
9928
9929    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9930            boolean isolated, int isolatedUid) {
9931        String proc = customProcess != null ? customProcess : info.processName;
9932        BatteryStatsImpl.Uid.Proc ps = null;
9933        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9934        int uid = info.uid;
9935        if (isolated) {
9936            if (isolatedUid == 0) {
9937                int userId = UserHandle.getUserId(uid);
9938                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9939                while (true) {
9940                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9941                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9942                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9943                    }
9944                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9945                    mNextIsolatedProcessUid++;
9946                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9947                        // No process for this uid, use it.
9948                        break;
9949                    }
9950                    stepsLeft--;
9951                    if (stepsLeft <= 0) {
9952                        return null;
9953                    }
9954                }
9955            } else {
9956                // Special case for startIsolatedProcess (internal only), where
9957                // the uid of the isolated process is specified by the caller.
9958                uid = isolatedUid;
9959            }
9960        }
9961        return new ProcessRecord(stats, info, proc, uid);
9962    }
9963
9964    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9965            String abiOverride) {
9966        ProcessRecord app;
9967        if (!isolated) {
9968            app = getProcessRecordLocked(info.processName, info.uid, true);
9969        } else {
9970            app = null;
9971        }
9972
9973        if (app == null) {
9974            app = newProcessRecordLocked(info, null, isolated, 0);
9975            mProcessNames.put(info.processName, app.uid, app);
9976            if (isolated) {
9977                mIsolatedProcesses.put(app.uid, app);
9978            }
9979            updateLruProcessLocked(app, false, null);
9980            updateOomAdjLocked();
9981        }
9982
9983        // This package really, really can not be stopped.
9984        try {
9985            AppGlobals.getPackageManager().setPackageStoppedState(
9986                    info.packageName, false, UserHandle.getUserId(app.uid));
9987        } catch (RemoteException e) {
9988        } catch (IllegalArgumentException e) {
9989            Slog.w(TAG, "Failed trying to unstop package "
9990                    + info.packageName + ": " + e);
9991        }
9992
9993        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9994                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9995            app.persistent = true;
9996            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9997        }
9998        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9999            mPersistentStartingProcesses.add(app);
10000            startProcessLocked(app, "added application", app.processName, abiOverride,
10001                    null /* entryPoint */, null /* entryPointArgs */);
10002        }
10003
10004        return app;
10005    }
10006
10007    public void unhandledBack() {
10008        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10009                "unhandledBack()");
10010
10011        synchronized(this) {
10012            final long origId = Binder.clearCallingIdentity();
10013            try {
10014                getFocusedStack().unhandledBackLocked();
10015            } finally {
10016                Binder.restoreCallingIdentity(origId);
10017            }
10018        }
10019    }
10020
10021    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10022        enforceNotIsolatedCaller("openContentUri");
10023        final int userId = UserHandle.getCallingUserId();
10024        String name = uri.getAuthority();
10025        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10026        ParcelFileDescriptor pfd = null;
10027        if (cph != null) {
10028            // We record the binder invoker's uid in thread-local storage before
10029            // going to the content provider to open the file.  Later, in the code
10030            // that handles all permissions checks, we look for this uid and use
10031            // that rather than the Activity Manager's own uid.  The effect is that
10032            // we do the check against the caller's permissions even though it looks
10033            // to the content provider like the Activity Manager itself is making
10034            // the request.
10035            Binder token = new Binder();
10036            sCallerIdentity.set(new Identity(
10037                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10038            try {
10039                pfd = cph.provider.openFile(null, uri, "r", null, token);
10040            } catch (FileNotFoundException e) {
10041                // do nothing; pfd will be returned null
10042            } finally {
10043                // Ensure that whatever happens, we clean up the identity state
10044                sCallerIdentity.remove();
10045                // Ensure we're done with the provider.
10046                removeContentProviderExternalUnchecked(name, null, userId);
10047            }
10048        } else {
10049            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10050        }
10051        return pfd;
10052    }
10053
10054    // Actually is sleeping or shutting down or whatever else in the future
10055    // is an inactive state.
10056    public boolean isSleepingOrShuttingDown() {
10057        return isSleeping() || mShuttingDown;
10058    }
10059
10060    public boolean isSleeping() {
10061        return mSleeping;
10062    }
10063
10064    void onWakefulnessChanged(int wakefulness) {
10065        synchronized(this) {
10066            mWakefulness = wakefulness;
10067            updateSleepIfNeededLocked();
10068        }
10069    }
10070
10071    void finishRunningVoiceLocked() {
10072        if (mRunningVoice) {
10073            mRunningVoice = false;
10074            updateSleepIfNeededLocked();
10075        }
10076    }
10077
10078    void updateSleepIfNeededLocked() {
10079        if (mSleeping && !shouldSleepLocked()) {
10080            mSleeping = false;
10081            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10082        } else if (!mSleeping && shouldSleepLocked()) {
10083            mSleeping = true;
10084            mStackSupervisor.goingToSleepLocked();
10085
10086            // Initialize the wake times of all processes.
10087            checkExcessivePowerUsageLocked(false);
10088            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10089            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10090            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10091        }
10092    }
10093
10094    private boolean shouldSleepLocked() {
10095        // Resume applications while running a voice interactor.
10096        if (mRunningVoice) {
10097            return false;
10098        }
10099
10100        switch (mWakefulness) {
10101            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10102            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10103                // If we're interactive but applications are already paused then defer
10104                // resuming them until the lock screen is hidden.
10105                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10106            case PowerManagerInternal.WAKEFULNESS_DOZING:
10107                // If we're dozing then pause applications whenever the lock screen is shown.
10108                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10109            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10110            default:
10111                // If we're asleep then pause applications unconditionally.
10112                return true;
10113        }
10114    }
10115
10116    /** Pokes the task persister. */
10117    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10118        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10119            // Never persist the home stack.
10120            return;
10121        }
10122        mTaskPersister.wakeup(task, flush);
10123    }
10124
10125    /** Notifies all listeners when the task stack has changed. */
10126    void notifyTaskStackChangedLocked() {
10127        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10128        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10129        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10130    }
10131
10132    @Override
10133    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10134        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10135    }
10136
10137    @Override
10138    public boolean shutdown(int timeout) {
10139        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10140                != PackageManager.PERMISSION_GRANTED) {
10141            throw new SecurityException("Requires permission "
10142                    + android.Manifest.permission.SHUTDOWN);
10143        }
10144
10145        boolean timedout = false;
10146
10147        synchronized(this) {
10148            mShuttingDown = true;
10149            updateEventDispatchingLocked();
10150            timedout = mStackSupervisor.shutdownLocked(timeout);
10151        }
10152
10153        mAppOpsService.shutdown();
10154        if (mUsageStatsService != null) {
10155            mUsageStatsService.prepareShutdown();
10156        }
10157        mBatteryStatsService.shutdown();
10158        synchronized (this) {
10159            mProcessStats.shutdownLocked();
10160            notifyTaskPersisterLocked(null, true);
10161        }
10162
10163        return timedout;
10164    }
10165
10166    public final void activitySlept(IBinder token) {
10167        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10168
10169        final long origId = Binder.clearCallingIdentity();
10170
10171        synchronized (this) {
10172            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10173            if (r != null) {
10174                mStackSupervisor.activitySleptLocked(r);
10175            }
10176        }
10177
10178        Binder.restoreCallingIdentity(origId);
10179    }
10180
10181    private String lockScreenShownToString() {
10182        switch (mLockScreenShown) {
10183            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10184            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10185            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10186            default: return "Unknown=" + mLockScreenShown;
10187        }
10188    }
10189
10190    void logLockScreen(String msg) {
10191        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10192                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10193                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10194                + " mSleeping=" + mSleeping);
10195    }
10196
10197    void startRunningVoiceLocked() {
10198        if (!mRunningVoice) {
10199            mRunningVoice = true;
10200            updateSleepIfNeededLocked();
10201        }
10202    }
10203
10204    private void updateEventDispatchingLocked() {
10205        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10206    }
10207
10208    public void setLockScreenShown(boolean shown) {
10209        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10210                != PackageManager.PERMISSION_GRANTED) {
10211            throw new SecurityException("Requires permission "
10212                    + android.Manifest.permission.DEVICE_POWER);
10213        }
10214
10215        synchronized(this) {
10216            long ident = Binder.clearCallingIdentity();
10217            try {
10218                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10219                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10220                updateSleepIfNeededLocked();
10221            } finally {
10222                Binder.restoreCallingIdentity(ident);
10223            }
10224        }
10225    }
10226
10227    @Override
10228    public void stopAppSwitches() {
10229        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10230                != PackageManager.PERMISSION_GRANTED) {
10231            throw new SecurityException("Requires permission "
10232                    + android.Manifest.permission.STOP_APP_SWITCHES);
10233        }
10234
10235        synchronized(this) {
10236            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10237                    + APP_SWITCH_DELAY_TIME;
10238            mDidAppSwitch = false;
10239            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10240            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10241            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10242        }
10243    }
10244
10245    public void resumeAppSwitches() {
10246        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10247                != PackageManager.PERMISSION_GRANTED) {
10248            throw new SecurityException("Requires permission "
10249                    + android.Manifest.permission.STOP_APP_SWITCHES);
10250        }
10251
10252        synchronized(this) {
10253            // Note that we don't execute any pending app switches... we will
10254            // let those wait until either the timeout, or the next start
10255            // activity request.
10256            mAppSwitchesAllowedTime = 0;
10257        }
10258    }
10259
10260    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10261            int callingPid, int callingUid, String name) {
10262        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10263            return true;
10264        }
10265
10266        int perm = checkComponentPermission(
10267                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10268                sourceUid, -1, true);
10269        if (perm == PackageManager.PERMISSION_GRANTED) {
10270            return true;
10271        }
10272
10273        // If the actual IPC caller is different from the logical source, then
10274        // also see if they are allowed to control app switches.
10275        if (callingUid != -1 && callingUid != sourceUid) {
10276            perm = checkComponentPermission(
10277                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10278                    callingUid, -1, true);
10279            if (perm == PackageManager.PERMISSION_GRANTED) {
10280                return true;
10281            }
10282        }
10283
10284        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10285        return false;
10286    }
10287
10288    public void setDebugApp(String packageName, boolean waitForDebugger,
10289            boolean persistent) {
10290        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10291                "setDebugApp()");
10292
10293        long ident = Binder.clearCallingIdentity();
10294        try {
10295            // Note that this is not really thread safe if there are multiple
10296            // callers into it at the same time, but that's not a situation we
10297            // care about.
10298            if (persistent) {
10299                final ContentResolver resolver = mContext.getContentResolver();
10300                Settings.Global.putString(
10301                    resolver, Settings.Global.DEBUG_APP,
10302                    packageName);
10303                Settings.Global.putInt(
10304                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10305                    waitForDebugger ? 1 : 0);
10306            }
10307
10308            synchronized (this) {
10309                if (!persistent) {
10310                    mOrigDebugApp = mDebugApp;
10311                    mOrigWaitForDebugger = mWaitForDebugger;
10312                }
10313                mDebugApp = packageName;
10314                mWaitForDebugger = waitForDebugger;
10315                mDebugTransient = !persistent;
10316                if (packageName != null) {
10317                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10318                            false, UserHandle.USER_ALL, "set debug app");
10319                }
10320            }
10321        } finally {
10322            Binder.restoreCallingIdentity(ident);
10323        }
10324    }
10325
10326    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10327        synchronized (this) {
10328            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10329            if (!isDebuggable) {
10330                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10331                    throw new SecurityException("Process not debuggable: " + app.packageName);
10332                }
10333            }
10334
10335            mOpenGlTraceApp = processName;
10336        }
10337    }
10338
10339    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10340        synchronized (this) {
10341            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10342            if (!isDebuggable) {
10343                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10344                    throw new SecurityException("Process not debuggable: " + app.packageName);
10345                }
10346            }
10347            mProfileApp = processName;
10348            mProfileFile = profilerInfo.profileFile;
10349            if (mProfileFd != null) {
10350                try {
10351                    mProfileFd.close();
10352                } catch (IOException e) {
10353                }
10354                mProfileFd = null;
10355            }
10356            mProfileFd = profilerInfo.profileFd;
10357            mSamplingInterval = profilerInfo.samplingInterval;
10358            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10359            mProfileType = 0;
10360        }
10361    }
10362
10363    @Override
10364    public void setAlwaysFinish(boolean enabled) {
10365        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10366                "setAlwaysFinish()");
10367
10368        Settings.Global.putInt(
10369                mContext.getContentResolver(),
10370                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10371
10372        synchronized (this) {
10373            mAlwaysFinishActivities = enabled;
10374        }
10375    }
10376
10377    @Override
10378    public void setActivityController(IActivityController controller) {
10379        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10380                "setActivityController()");
10381        synchronized (this) {
10382            mController = controller;
10383            Watchdog.getInstance().setActivityController(controller);
10384        }
10385    }
10386
10387    @Override
10388    public void setUserIsMonkey(boolean userIsMonkey) {
10389        synchronized (this) {
10390            synchronized (mPidsSelfLocked) {
10391                final int callingPid = Binder.getCallingPid();
10392                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10393                if (precessRecord == null) {
10394                    throw new SecurityException("Unknown process: " + callingPid);
10395                }
10396                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10397                    throw new SecurityException("Only an instrumentation process "
10398                            + "with a UiAutomation can call setUserIsMonkey");
10399                }
10400            }
10401            mUserIsMonkey = userIsMonkey;
10402        }
10403    }
10404
10405    @Override
10406    public boolean isUserAMonkey() {
10407        synchronized (this) {
10408            // If there is a controller also implies the user is a monkey.
10409            return (mUserIsMonkey || mController != null);
10410        }
10411    }
10412
10413    public void requestBugReport() {
10414        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10415        SystemProperties.set("ctl.start", "bugreport");
10416    }
10417
10418    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10419        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10420    }
10421
10422    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10423        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10424            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10425        }
10426        return KEY_DISPATCHING_TIMEOUT;
10427    }
10428
10429    @Override
10430    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10431        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10432                != PackageManager.PERMISSION_GRANTED) {
10433            throw new SecurityException("Requires permission "
10434                    + android.Manifest.permission.FILTER_EVENTS);
10435        }
10436        ProcessRecord proc;
10437        long timeout;
10438        synchronized (this) {
10439            synchronized (mPidsSelfLocked) {
10440                proc = mPidsSelfLocked.get(pid);
10441            }
10442            timeout = getInputDispatchingTimeoutLocked(proc);
10443        }
10444
10445        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10446            return -1;
10447        }
10448
10449        return timeout;
10450    }
10451
10452    /**
10453     * Handle input dispatching timeouts.
10454     * Returns whether input dispatching should be aborted or not.
10455     */
10456    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10457            final ActivityRecord activity, final ActivityRecord parent,
10458            final boolean aboveSystem, String reason) {
10459        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10460                != PackageManager.PERMISSION_GRANTED) {
10461            throw new SecurityException("Requires permission "
10462                    + android.Manifest.permission.FILTER_EVENTS);
10463        }
10464
10465        final String annotation;
10466        if (reason == null) {
10467            annotation = "Input dispatching timed out";
10468        } else {
10469            annotation = "Input dispatching timed out (" + reason + ")";
10470        }
10471
10472        if (proc != null) {
10473            synchronized (this) {
10474                if (proc.debugging) {
10475                    return false;
10476                }
10477
10478                if (mDidDexOpt) {
10479                    // Give more time since we were dexopting.
10480                    mDidDexOpt = false;
10481                    return false;
10482                }
10483
10484                if (proc.instrumentationClass != null) {
10485                    Bundle info = new Bundle();
10486                    info.putString("shortMsg", "keyDispatchingTimedOut");
10487                    info.putString("longMsg", annotation);
10488                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10489                    return true;
10490                }
10491            }
10492            mHandler.post(new Runnable() {
10493                @Override
10494                public void run() {
10495                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10496                }
10497            });
10498        }
10499
10500        return true;
10501    }
10502
10503    public Bundle getAssistContextExtras(int requestType) {
10504        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10505                UserHandle.getCallingUserId());
10506        if (pae == null) {
10507            return null;
10508        }
10509        synchronized (pae) {
10510            while (!pae.haveResult) {
10511                try {
10512                    pae.wait();
10513                } catch (InterruptedException e) {
10514                }
10515            }
10516            if (pae.result != null) {
10517                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10518            }
10519        }
10520        synchronized (this) {
10521            mPendingAssistExtras.remove(pae);
10522            mHandler.removeCallbacks(pae);
10523        }
10524        return pae.extras;
10525    }
10526
10527    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10528            int userHandle) {
10529        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10530                "getAssistContextExtras()");
10531        PendingAssistExtras pae;
10532        Bundle extras = new Bundle();
10533        synchronized (this) {
10534            ActivityRecord activity = getFocusedStack().mResumedActivity;
10535            if (activity == null) {
10536                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10537                return null;
10538            }
10539            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10540            if (activity.app == null || activity.app.thread == null) {
10541                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10542                return null;
10543            }
10544            if (activity.app.pid == Binder.getCallingPid()) {
10545                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10546                return null;
10547            }
10548            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10549            try {
10550                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10551                        requestType);
10552                mPendingAssistExtras.add(pae);
10553                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10554            } catch (RemoteException e) {
10555                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10556                return null;
10557            }
10558            return pae;
10559        }
10560    }
10561
10562    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10563        PendingAssistExtras pae = (PendingAssistExtras)token;
10564        synchronized (pae) {
10565            pae.result = extras;
10566            pae.haveResult = true;
10567            pae.notifyAll();
10568            if (pae.intent == null) {
10569                // Caller is just waiting for the result.
10570                return;
10571            }
10572        }
10573
10574        // We are now ready to launch the assist activity.
10575        synchronized (this) {
10576            boolean exists = mPendingAssistExtras.remove(pae);
10577            mHandler.removeCallbacks(pae);
10578            if (!exists) {
10579                // Timed out.
10580                return;
10581            }
10582        }
10583        pae.intent.replaceExtras(extras);
10584        if (pae.hint != null) {
10585            pae.intent.putExtra(pae.hint, true);
10586        }
10587        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10588                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10589                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10590        closeSystemDialogs("assist");
10591        try {
10592            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10593        } catch (ActivityNotFoundException e) {
10594            Slog.w(TAG, "No activity to handle assist action.", e);
10595        }
10596    }
10597
10598    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10599        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10600    }
10601
10602    public void registerProcessObserver(IProcessObserver observer) {
10603        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10604                "registerProcessObserver()");
10605        synchronized (this) {
10606            mProcessObservers.register(observer);
10607        }
10608    }
10609
10610    @Override
10611    public void unregisterProcessObserver(IProcessObserver observer) {
10612        synchronized (this) {
10613            mProcessObservers.unregister(observer);
10614        }
10615    }
10616
10617    @Override
10618    public boolean convertFromTranslucent(IBinder token) {
10619        final long origId = Binder.clearCallingIdentity();
10620        try {
10621            synchronized (this) {
10622                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10623                if (r == null) {
10624                    return false;
10625                }
10626                final boolean translucentChanged = r.changeWindowTranslucency(true);
10627                if (translucentChanged) {
10628                    r.task.stack.releaseBackgroundResources();
10629                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10630                }
10631                mWindowManager.setAppFullscreen(token, true);
10632                return translucentChanged;
10633            }
10634        } finally {
10635            Binder.restoreCallingIdentity(origId);
10636        }
10637    }
10638
10639    @Override
10640    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10641        final long origId = Binder.clearCallingIdentity();
10642        try {
10643            synchronized (this) {
10644                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10645                if (r == null) {
10646                    return false;
10647                }
10648                int index = r.task.mActivities.lastIndexOf(r);
10649                if (index > 0) {
10650                    ActivityRecord under = r.task.mActivities.get(index - 1);
10651                    under.returningOptions = options;
10652                }
10653                final boolean translucentChanged = r.changeWindowTranslucency(false);
10654                if (translucentChanged) {
10655                    r.task.stack.convertToTranslucent(r);
10656                }
10657                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10658                mWindowManager.setAppFullscreen(token, false);
10659                return translucentChanged;
10660            }
10661        } finally {
10662            Binder.restoreCallingIdentity(origId);
10663        }
10664    }
10665
10666    @Override
10667    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10668        final long origId = Binder.clearCallingIdentity();
10669        try {
10670            synchronized (this) {
10671                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10672                if (r != null) {
10673                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10674                }
10675            }
10676            return false;
10677        } finally {
10678            Binder.restoreCallingIdentity(origId);
10679        }
10680    }
10681
10682    @Override
10683    public boolean isBackgroundVisibleBehind(IBinder token) {
10684        final long origId = Binder.clearCallingIdentity();
10685        try {
10686            synchronized (this) {
10687                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10688                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10689                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10690                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10691                return visible;
10692            }
10693        } finally {
10694            Binder.restoreCallingIdentity(origId);
10695        }
10696    }
10697
10698    @Override
10699    public ActivityOptions getActivityOptions(IBinder token) {
10700        final long origId = Binder.clearCallingIdentity();
10701        try {
10702            synchronized (this) {
10703                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10704                if (r != null) {
10705                    final ActivityOptions activityOptions = r.pendingOptions;
10706                    r.pendingOptions = null;
10707                    return activityOptions;
10708                }
10709                return null;
10710            }
10711        } finally {
10712            Binder.restoreCallingIdentity(origId);
10713        }
10714    }
10715
10716    @Override
10717    public void setImmersive(IBinder token, boolean immersive) {
10718        synchronized(this) {
10719            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10720            if (r == null) {
10721                throw new IllegalArgumentException();
10722            }
10723            r.immersive = immersive;
10724
10725            // update associated state if we're frontmost
10726            if (r == mFocusedActivity) {
10727                if (DEBUG_IMMERSIVE) {
10728                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10729                }
10730                applyUpdateLockStateLocked(r);
10731            }
10732        }
10733    }
10734
10735    @Override
10736    public boolean isImmersive(IBinder token) {
10737        synchronized (this) {
10738            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10739            if (r == null) {
10740                throw new IllegalArgumentException();
10741            }
10742            return r.immersive;
10743        }
10744    }
10745
10746    public boolean isTopActivityImmersive() {
10747        enforceNotIsolatedCaller("startActivity");
10748        synchronized (this) {
10749            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10750            return (r != null) ? r.immersive : false;
10751        }
10752    }
10753
10754    @Override
10755    public boolean isTopOfTask(IBinder token) {
10756        synchronized (this) {
10757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10758            if (r == null) {
10759                throw new IllegalArgumentException();
10760            }
10761            return r.task.getTopActivity() == r;
10762        }
10763    }
10764
10765    public final void enterSafeMode() {
10766        synchronized(this) {
10767            // It only makes sense to do this before the system is ready
10768            // and started launching other packages.
10769            if (!mSystemReady) {
10770                try {
10771                    AppGlobals.getPackageManager().enterSafeMode();
10772                } catch (RemoteException e) {
10773                }
10774            }
10775
10776            mSafeMode = true;
10777        }
10778    }
10779
10780    public final void showSafeModeOverlay() {
10781        View v = LayoutInflater.from(mContext).inflate(
10782                com.android.internal.R.layout.safe_mode, null);
10783        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10784        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10785        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10786        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10787        lp.gravity = Gravity.BOTTOM | Gravity.START;
10788        lp.format = v.getBackground().getOpacity();
10789        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10790                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10791        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10792        ((WindowManager)mContext.getSystemService(
10793                Context.WINDOW_SERVICE)).addView(v, lp);
10794    }
10795
10796    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10797        if (!(sender instanceof PendingIntentRecord)) {
10798            return;
10799        }
10800        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10801        synchronized (stats) {
10802            if (mBatteryStatsService.isOnBattery()) {
10803                mBatteryStatsService.enforceCallingPermission();
10804                PendingIntentRecord rec = (PendingIntentRecord)sender;
10805                int MY_UID = Binder.getCallingUid();
10806                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10807                BatteryStatsImpl.Uid.Pkg pkg =
10808                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10809                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10810                pkg.incWakeupsLocked();
10811            }
10812        }
10813    }
10814
10815    public boolean killPids(int[] pids, String pReason, boolean secure) {
10816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10817            throw new SecurityException("killPids only available to the system");
10818        }
10819        String reason = (pReason == null) ? "Unknown" : pReason;
10820        // XXX Note: don't acquire main activity lock here, because the window
10821        // manager calls in with its locks held.
10822
10823        boolean killed = false;
10824        synchronized (mPidsSelfLocked) {
10825            int[] types = new int[pids.length];
10826            int worstType = 0;
10827            for (int i=0; i<pids.length; i++) {
10828                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10829                if (proc != null) {
10830                    int type = proc.setAdj;
10831                    types[i] = type;
10832                    if (type > worstType) {
10833                        worstType = type;
10834                    }
10835                }
10836            }
10837
10838            // If the worst oom_adj is somewhere in the cached proc LRU range,
10839            // then constrain it so we will kill all cached procs.
10840            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10841                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10842                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10843            }
10844
10845            // If this is not a secure call, don't let it kill processes that
10846            // are important.
10847            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10848                worstType = ProcessList.SERVICE_ADJ;
10849            }
10850
10851            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10852            for (int i=0; i<pids.length; i++) {
10853                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10854                if (proc == null) {
10855                    continue;
10856                }
10857                int adj = proc.setAdj;
10858                if (adj >= worstType && !proc.killedByAm) {
10859                    proc.kill(reason, true);
10860                    killed = true;
10861                }
10862            }
10863        }
10864        return killed;
10865    }
10866
10867    @Override
10868    public void killUid(int uid, String reason) {
10869        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10870            throw new SecurityException("killUid only available to the system");
10871        }
10872        synchronized (this) {
10873            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10874                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10875                    reason != null ? reason : "kill uid");
10876        }
10877    }
10878
10879    @Override
10880    public boolean killProcessesBelowForeground(String reason) {
10881        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10882            throw new SecurityException("killProcessesBelowForeground() only available to system");
10883        }
10884
10885        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10886    }
10887
10888    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10889        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10890            throw new SecurityException("killProcessesBelowAdj() only available to system");
10891        }
10892
10893        boolean killed = false;
10894        synchronized (mPidsSelfLocked) {
10895            final int size = mPidsSelfLocked.size();
10896            for (int i = 0; i < size; i++) {
10897                final int pid = mPidsSelfLocked.keyAt(i);
10898                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10899                if (proc == null) continue;
10900
10901                final int adj = proc.setAdj;
10902                if (adj > belowAdj && !proc.killedByAm) {
10903                    proc.kill(reason, true);
10904                    killed = true;
10905                }
10906            }
10907        }
10908        return killed;
10909    }
10910
10911    @Override
10912    public void hang(final IBinder who, boolean allowRestart) {
10913        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10914                != PackageManager.PERMISSION_GRANTED) {
10915            throw new SecurityException("Requires permission "
10916                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10917        }
10918
10919        final IBinder.DeathRecipient death = new DeathRecipient() {
10920            @Override
10921            public void binderDied() {
10922                synchronized (this) {
10923                    notifyAll();
10924                }
10925            }
10926        };
10927
10928        try {
10929            who.linkToDeath(death, 0);
10930        } catch (RemoteException e) {
10931            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10932            return;
10933        }
10934
10935        synchronized (this) {
10936            Watchdog.getInstance().setAllowRestart(allowRestart);
10937            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10938            synchronized (death) {
10939                while (who.isBinderAlive()) {
10940                    try {
10941                        death.wait();
10942                    } catch (InterruptedException e) {
10943                    }
10944                }
10945            }
10946            Watchdog.getInstance().setAllowRestart(true);
10947        }
10948    }
10949
10950    @Override
10951    public void restart() {
10952        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10953                != PackageManager.PERMISSION_GRANTED) {
10954            throw new SecurityException("Requires permission "
10955                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10956        }
10957
10958        Log.i(TAG, "Sending shutdown broadcast...");
10959
10960        BroadcastReceiver br = new BroadcastReceiver() {
10961            @Override public void onReceive(Context context, Intent intent) {
10962                // Now the broadcast is done, finish up the low-level shutdown.
10963                Log.i(TAG, "Shutting down activity manager...");
10964                shutdown(10000);
10965                Log.i(TAG, "Shutdown complete, restarting!");
10966                Process.killProcess(Process.myPid());
10967                System.exit(10);
10968            }
10969        };
10970
10971        // First send the high-level shut down broadcast.
10972        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10973        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10974        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10975        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10976        mContext.sendOrderedBroadcastAsUser(intent,
10977                UserHandle.ALL, null, br, mHandler, 0, null, null);
10978        */
10979        br.onReceive(mContext, intent);
10980    }
10981
10982    private long getLowRamTimeSinceIdle(long now) {
10983        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10984    }
10985
10986    @Override
10987    public void performIdleMaintenance() {
10988        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10989                != PackageManager.PERMISSION_GRANTED) {
10990            throw new SecurityException("Requires permission "
10991                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10992        }
10993
10994        synchronized (this) {
10995            final long now = SystemClock.uptimeMillis();
10996            final long timeSinceLastIdle = now - mLastIdleTime;
10997            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10998            mLastIdleTime = now;
10999            mLowRamTimeSinceLastIdle = 0;
11000            if (mLowRamStartTime != 0) {
11001                mLowRamStartTime = now;
11002            }
11003
11004            StringBuilder sb = new StringBuilder(128);
11005            sb.append("Idle maintenance over ");
11006            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11007            sb.append(" low RAM for ");
11008            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11009            Slog.i(TAG, sb.toString());
11010
11011            // If at least 1/3 of our time since the last idle period has been spent
11012            // with RAM low, then we want to kill processes.
11013            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11014
11015            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11016                ProcessRecord proc = mLruProcesses.get(i);
11017                if (proc.notCachedSinceIdle) {
11018                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11019                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11020                        if (doKilling && proc.initialIdlePss != 0
11021                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11022                            sb = new StringBuilder(128);
11023                            sb.append("Kill");
11024                            sb.append(proc.processName);
11025                            sb.append(" in idle maint: pss=");
11026                            sb.append(proc.lastPss);
11027                            sb.append(", initialPss=");
11028                            sb.append(proc.initialIdlePss);
11029                            sb.append(", period=");
11030                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11031                            sb.append(", lowRamPeriod=");
11032                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11033                            Slog.wtfQuiet(TAG, sb.toString());
11034                            proc.kill("idle maint (pss " + proc.lastPss
11035                                    + " from " + proc.initialIdlePss + ")", true);
11036                        }
11037                    }
11038                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11039                    proc.notCachedSinceIdle = true;
11040                    proc.initialIdlePss = 0;
11041                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11042                            mTestPssMode, isSleeping(), now);
11043                }
11044            }
11045
11046            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11047            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11048        }
11049    }
11050
11051    private void retrieveSettings() {
11052        final ContentResolver resolver = mContext.getContentResolver();
11053        String debugApp = Settings.Global.getString(
11054            resolver, Settings.Global.DEBUG_APP);
11055        boolean waitForDebugger = Settings.Global.getInt(
11056            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11057        boolean alwaysFinishActivities = Settings.Global.getInt(
11058            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11059        boolean forceRtl = Settings.Global.getInt(
11060                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11061        // Transfer any global setting for forcing RTL layout, into a System Property
11062        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11063
11064        Configuration configuration = new Configuration();
11065        Settings.System.getConfiguration(resolver, configuration);
11066        if (forceRtl) {
11067            // This will take care of setting the correct layout direction flags
11068            configuration.setLayoutDirection(configuration.locale);
11069        }
11070
11071        synchronized (this) {
11072            mDebugApp = mOrigDebugApp = debugApp;
11073            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11074            mAlwaysFinishActivities = alwaysFinishActivities;
11075            // This happens before any activities are started, so we can
11076            // change mConfiguration in-place.
11077            updateConfigurationLocked(configuration, null, false, true);
11078            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11079        }
11080    }
11081
11082    /** Loads resources after the current configuration has been set. */
11083    private void loadResourcesOnSystemReady() {
11084        final Resources res = mContext.getResources();
11085        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11086        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11087        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11088    }
11089
11090    public boolean testIsSystemReady() {
11091        // no need to synchronize(this) just to read & return the value
11092        return mSystemReady;
11093    }
11094
11095    private static File getCalledPreBootReceiversFile() {
11096        File dataDir = Environment.getDataDirectory();
11097        File systemDir = new File(dataDir, "system");
11098        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11099        return fname;
11100    }
11101
11102    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11103        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11104        File file = getCalledPreBootReceiversFile();
11105        FileInputStream fis = null;
11106        try {
11107            fis = new FileInputStream(file);
11108            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11109            int fvers = dis.readInt();
11110            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11111                String vers = dis.readUTF();
11112                String codename = dis.readUTF();
11113                String build = dis.readUTF();
11114                if (android.os.Build.VERSION.RELEASE.equals(vers)
11115                        && android.os.Build.VERSION.CODENAME.equals(codename)
11116                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11117                    int num = dis.readInt();
11118                    while (num > 0) {
11119                        num--;
11120                        String pkg = dis.readUTF();
11121                        String cls = dis.readUTF();
11122                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11123                    }
11124                }
11125            }
11126        } catch (FileNotFoundException e) {
11127        } catch (IOException e) {
11128            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11129        } finally {
11130            if (fis != null) {
11131                try {
11132                    fis.close();
11133                } catch (IOException e) {
11134                }
11135            }
11136        }
11137        return lastDoneReceivers;
11138    }
11139
11140    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11141        File file = getCalledPreBootReceiversFile();
11142        FileOutputStream fos = null;
11143        DataOutputStream dos = null;
11144        try {
11145            fos = new FileOutputStream(file);
11146            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11147            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11148            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11149            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11150            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11151            dos.writeInt(list.size());
11152            for (int i=0; i<list.size(); i++) {
11153                dos.writeUTF(list.get(i).getPackageName());
11154                dos.writeUTF(list.get(i).getClassName());
11155            }
11156        } catch (IOException e) {
11157            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11158            file.delete();
11159        } finally {
11160            FileUtils.sync(fos);
11161            if (dos != null) {
11162                try {
11163                    dos.close();
11164                } catch (IOException e) {
11165                    // TODO Auto-generated catch block
11166                    e.printStackTrace();
11167                }
11168            }
11169        }
11170    }
11171
11172    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11173            ArrayList<ComponentName> doneReceivers, int userId) {
11174        boolean waitingUpdate = false;
11175        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11176        List<ResolveInfo> ris = null;
11177        try {
11178            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11179                    intent, null, 0, userId);
11180        } catch (RemoteException e) {
11181        }
11182        if (ris != null) {
11183            for (int i=ris.size()-1; i>=0; i--) {
11184                if ((ris.get(i).activityInfo.applicationInfo.flags
11185                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11186                    ris.remove(i);
11187                }
11188            }
11189            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11190
11191            // For User 0, load the version number. When delivering to a new user, deliver
11192            // to all receivers.
11193            if (userId == UserHandle.USER_OWNER) {
11194                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11195                for (int i=0; i<ris.size(); i++) {
11196                    ActivityInfo ai = ris.get(i).activityInfo;
11197                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11198                    if (lastDoneReceivers.contains(comp)) {
11199                        // We already did the pre boot receiver for this app with the current
11200                        // platform version, so don't do it again...
11201                        ris.remove(i);
11202                        i--;
11203                        // ...however, do keep it as one that has been done, so we don't
11204                        // forget about it when rewriting the file of last done receivers.
11205                        doneReceivers.add(comp);
11206                    }
11207                }
11208            }
11209
11210            // If primary user, send broadcast to all available users, else just to userId
11211            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11212                    : new int[] { userId };
11213            for (int i = 0; i < ris.size(); i++) {
11214                ActivityInfo ai = ris.get(i).activityInfo;
11215                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11216                doneReceivers.add(comp);
11217                intent.setComponent(comp);
11218                for (int j=0; j<users.length; j++) {
11219                    IIntentReceiver finisher = null;
11220                    // On last receiver and user, set up a completion callback
11221                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11222                        finisher = new IIntentReceiver.Stub() {
11223                            public void performReceive(Intent intent, int resultCode,
11224                                    String data, Bundle extras, boolean ordered,
11225                                    boolean sticky, int sendingUser) {
11226                                // The raw IIntentReceiver interface is called
11227                                // with the AM lock held, so redispatch to
11228                                // execute our code without the lock.
11229                                mHandler.post(onFinishCallback);
11230                            }
11231                        };
11232                    }
11233                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11234                            + " for user " + users[j]);
11235                    broadcastIntentLocked(null, null, intent, null, finisher,
11236                            0, null, null, null, AppOpsManager.OP_NONE,
11237                            true, false, MY_PID, Process.SYSTEM_UID,
11238                            users[j]);
11239                    if (finisher != null) {
11240                        waitingUpdate = true;
11241                    }
11242                }
11243            }
11244        }
11245
11246        return waitingUpdate;
11247    }
11248
11249    public void systemReady(final Runnable goingCallback) {
11250        synchronized(this) {
11251            if (mSystemReady) {
11252                // If we're done calling all the receivers, run the next "boot phase" passed in
11253                // by the SystemServer
11254                if (goingCallback != null) {
11255                    goingCallback.run();
11256                }
11257                return;
11258            }
11259
11260            // Make sure we have the current profile info, since it is needed for
11261            // security checks.
11262            updateCurrentProfileIdsLocked();
11263
11264            if (mRecentTasks == null) {
11265                mRecentTasks = mTaskPersister.restoreTasksLocked();
11266                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11267                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11268                mTaskPersister.startPersisting();
11269            }
11270
11271            // Check to see if there are any update receivers to run.
11272            if (!mDidUpdate) {
11273                if (mWaitingUpdate) {
11274                    return;
11275                }
11276                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11277                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11278                    public void run() {
11279                        synchronized (ActivityManagerService.this) {
11280                            mDidUpdate = true;
11281                        }
11282                        writeLastDonePreBootReceivers(doneReceivers);
11283                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11284                                false);
11285                        systemReady(goingCallback);
11286                    }
11287                }, doneReceivers, UserHandle.USER_OWNER);
11288
11289                if (mWaitingUpdate) {
11290                    return;
11291                }
11292                mDidUpdate = true;
11293            }
11294
11295            mAppOpsService.systemReady();
11296            mSystemReady = true;
11297        }
11298
11299        ArrayList<ProcessRecord> procsToKill = null;
11300        synchronized(mPidsSelfLocked) {
11301            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11302                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11303                if (!isAllowedWhileBooting(proc.info)){
11304                    if (procsToKill == null) {
11305                        procsToKill = new ArrayList<ProcessRecord>();
11306                    }
11307                    procsToKill.add(proc);
11308                }
11309            }
11310        }
11311
11312        synchronized(this) {
11313            if (procsToKill != null) {
11314                for (int i=procsToKill.size()-1; i>=0; i--) {
11315                    ProcessRecord proc = procsToKill.get(i);
11316                    Slog.i(TAG, "Removing system update proc: " + proc);
11317                    removeProcessLocked(proc, true, false, "system update done");
11318                }
11319            }
11320
11321            // Now that we have cleaned up any update processes, we
11322            // are ready to start launching real processes and know that
11323            // we won't trample on them any more.
11324            mProcessesReady = true;
11325        }
11326
11327        Slog.i(TAG, "System now ready");
11328        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11329            SystemClock.uptimeMillis());
11330
11331        synchronized(this) {
11332            // Make sure we have no pre-ready processes sitting around.
11333
11334            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11335                ResolveInfo ri = mContext.getPackageManager()
11336                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11337                                STOCK_PM_FLAGS);
11338                CharSequence errorMsg = null;
11339                if (ri != null) {
11340                    ActivityInfo ai = ri.activityInfo;
11341                    ApplicationInfo app = ai.applicationInfo;
11342                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11343                        mTopAction = Intent.ACTION_FACTORY_TEST;
11344                        mTopData = null;
11345                        mTopComponent = new ComponentName(app.packageName,
11346                                ai.name);
11347                    } else {
11348                        errorMsg = mContext.getResources().getText(
11349                                com.android.internal.R.string.factorytest_not_system);
11350                    }
11351                } else {
11352                    errorMsg = mContext.getResources().getText(
11353                            com.android.internal.R.string.factorytest_no_action);
11354                }
11355                if (errorMsg != null) {
11356                    mTopAction = null;
11357                    mTopData = null;
11358                    mTopComponent = null;
11359                    Message msg = Message.obtain();
11360                    msg.what = SHOW_FACTORY_ERROR_MSG;
11361                    msg.getData().putCharSequence("msg", errorMsg);
11362                    mHandler.sendMessage(msg);
11363                }
11364            }
11365        }
11366
11367        retrieveSettings();
11368        loadResourcesOnSystemReady();
11369
11370        synchronized (this) {
11371            readGrantedUriPermissionsLocked();
11372        }
11373
11374        if (goingCallback != null) goingCallback.run();
11375
11376        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11377                Integer.toString(mCurrentUserId), mCurrentUserId);
11378        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11379                Integer.toString(mCurrentUserId), mCurrentUserId);
11380        mSystemServiceManager.startUser(mCurrentUserId);
11381
11382        synchronized (this) {
11383            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11384                try {
11385                    List apps = AppGlobals.getPackageManager().
11386                        getPersistentApplications(STOCK_PM_FLAGS);
11387                    if (apps != null) {
11388                        int N = apps.size();
11389                        int i;
11390                        for (i=0; i<N; i++) {
11391                            ApplicationInfo info
11392                                = (ApplicationInfo)apps.get(i);
11393                            if (info != null &&
11394                                    !info.packageName.equals("android")) {
11395                                addAppLocked(info, false, null /* ABI override */);
11396                            }
11397                        }
11398                    }
11399                } catch (RemoteException ex) {
11400                    // pm is in same process, this will never happen.
11401                }
11402            }
11403
11404            // Start up initial activity.
11405            mBooting = true;
11406            startHomeActivityLocked(mCurrentUserId, "systemReady");
11407
11408            try {
11409                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11410                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11411                            + " data partition or your device will be unstable.");
11412                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11413                }
11414            } catch (RemoteException e) {
11415            }
11416
11417            if (!Build.isFingerprintConsistent()) {
11418                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11419                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11420            }
11421
11422            long ident = Binder.clearCallingIdentity();
11423            try {
11424                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11425                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11426                        | Intent.FLAG_RECEIVER_FOREGROUND);
11427                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11428                broadcastIntentLocked(null, null, intent,
11429                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11430                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11431                intent = new Intent(Intent.ACTION_USER_STARTING);
11432                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11433                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11434                broadcastIntentLocked(null, null, intent,
11435                        null, new IIntentReceiver.Stub() {
11436                            @Override
11437                            public void performReceive(Intent intent, int resultCode, String data,
11438                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11439                                    throws RemoteException {
11440                            }
11441                        }, 0, null, null,
11442                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11443                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11444            } catch (Throwable t) {
11445                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11446            } finally {
11447                Binder.restoreCallingIdentity(ident);
11448            }
11449            mStackSupervisor.resumeTopActivitiesLocked();
11450            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11451        }
11452    }
11453
11454    private boolean makeAppCrashingLocked(ProcessRecord app,
11455            String shortMsg, String longMsg, String stackTrace) {
11456        app.crashing = true;
11457        app.crashingReport = generateProcessError(app,
11458                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11459        startAppProblemLocked(app);
11460        app.stopFreezingAllLocked();
11461        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11462    }
11463
11464    private void makeAppNotRespondingLocked(ProcessRecord app,
11465            String activity, String shortMsg, String longMsg) {
11466        app.notResponding = true;
11467        app.notRespondingReport = generateProcessError(app,
11468                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11469                activity, shortMsg, longMsg, null);
11470        startAppProblemLocked(app);
11471        app.stopFreezingAllLocked();
11472    }
11473
11474    /**
11475     * Generate a process error record, suitable for attachment to a ProcessRecord.
11476     *
11477     * @param app The ProcessRecord in which the error occurred.
11478     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11479     *                      ActivityManager.AppErrorStateInfo
11480     * @param activity The activity associated with the crash, if known.
11481     * @param shortMsg Short message describing the crash.
11482     * @param longMsg Long message describing the crash.
11483     * @param stackTrace Full crash stack trace, may be null.
11484     *
11485     * @return Returns a fully-formed AppErrorStateInfo record.
11486     */
11487    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11488            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11489        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11490
11491        report.condition = condition;
11492        report.processName = app.processName;
11493        report.pid = app.pid;
11494        report.uid = app.info.uid;
11495        report.tag = activity;
11496        report.shortMsg = shortMsg;
11497        report.longMsg = longMsg;
11498        report.stackTrace = stackTrace;
11499
11500        return report;
11501    }
11502
11503    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11504        synchronized (this) {
11505            app.crashing = false;
11506            app.crashingReport = null;
11507            app.notResponding = false;
11508            app.notRespondingReport = null;
11509            if (app.anrDialog == fromDialog) {
11510                app.anrDialog = null;
11511            }
11512            if (app.waitDialog == fromDialog) {
11513                app.waitDialog = null;
11514            }
11515            if (app.pid > 0 && app.pid != MY_PID) {
11516                handleAppCrashLocked(app, null, null, null);
11517                app.kill("user request after error", true);
11518            }
11519        }
11520    }
11521
11522    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11523            String stackTrace) {
11524        long now = SystemClock.uptimeMillis();
11525
11526        Long crashTime;
11527        if (!app.isolated) {
11528            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11529        } else {
11530            crashTime = null;
11531        }
11532        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11533            // This process loses!
11534            Slog.w(TAG, "Process " + app.info.processName
11535                    + " has crashed too many times: killing!");
11536            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11537                    app.userId, app.info.processName, app.uid);
11538            mStackSupervisor.handleAppCrashLocked(app);
11539            if (!app.persistent) {
11540                // We don't want to start this process again until the user
11541                // explicitly does so...  but for persistent process, we really
11542                // need to keep it running.  If a persistent process is actually
11543                // repeatedly crashing, then badness for everyone.
11544                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11545                        app.info.processName);
11546                if (!app.isolated) {
11547                    // XXX We don't have a way to mark isolated processes
11548                    // as bad, since they don't have a peristent identity.
11549                    mBadProcesses.put(app.info.processName, app.uid,
11550                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11551                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11552                }
11553                app.bad = true;
11554                app.removed = true;
11555                // Don't let services in this process be restarted and potentially
11556                // annoy the user repeatedly.  Unless it is persistent, since those
11557                // processes run critical code.
11558                removeProcessLocked(app, false, false, "crash");
11559                mStackSupervisor.resumeTopActivitiesLocked();
11560                return false;
11561            }
11562            mStackSupervisor.resumeTopActivitiesLocked();
11563        } else {
11564            mStackSupervisor.finishTopRunningActivityLocked(app);
11565        }
11566
11567        // Bump up the crash count of any services currently running in the proc.
11568        for (int i=app.services.size()-1; i>=0; i--) {
11569            // Any services running in the application need to be placed
11570            // back in the pending list.
11571            ServiceRecord sr = app.services.valueAt(i);
11572            sr.crashCount++;
11573        }
11574
11575        // If the crashing process is what we consider to be the "home process" and it has been
11576        // replaced by a third-party app, clear the package preferred activities from packages
11577        // with a home activity running in the process to prevent a repeatedly crashing app
11578        // from blocking the user to manually clear the list.
11579        final ArrayList<ActivityRecord> activities = app.activities;
11580        if (app == mHomeProcess && activities.size() > 0
11581                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11582            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11583                final ActivityRecord r = activities.get(activityNdx);
11584                if (r.isHomeActivity()) {
11585                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11586                    try {
11587                        ActivityThread.getPackageManager()
11588                                .clearPackagePreferredActivities(r.packageName);
11589                    } catch (RemoteException c) {
11590                        // pm is in same process, this will never happen.
11591                    }
11592                }
11593            }
11594        }
11595
11596        if (!app.isolated) {
11597            // XXX Can't keep track of crash times for isolated processes,
11598            // because they don't have a perisistent identity.
11599            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11600        }
11601
11602        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11603        return true;
11604    }
11605
11606    void startAppProblemLocked(ProcessRecord app) {
11607        // If this app is not running under the current user, then we
11608        // can't give it a report button because that would require
11609        // launching the report UI under a different user.
11610        app.errorReportReceiver = null;
11611
11612        for (int userId : mCurrentProfileIds) {
11613            if (app.userId == userId) {
11614                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11615                        mContext, app.info.packageName, app.info.flags);
11616            }
11617        }
11618        skipCurrentReceiverLocked(app);
11619    }
11620
11621    void skipCurrentReceiverLocked(ProcessRecord app) {
11622        for (BroadcastQueue queue : mBroadcastQueues) {
11623            queue.skipCurrentReceiverLocked(app);
11624        }
11625    }
11626
11627    /**
11628     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11629     * The application process will exit immediately after this call returns.
11630     * @param app object of the crashing app, null for the system server
11631     * @param crashInfo describing the exception
11632     */
11633    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11634        ProcessRecord r = findAppProcess(app, "Crash");
11635        final String processName = app == null ? "system_server"
11636                : (r == null ? "unknown" : r.processName);
11637
11638        handleApplicationCrashInner("crash", r, processName, crashInfo);
11639    }
11640
11641    /* Native crash reporting uses this inner version because it needs to be somewhat
11642     * decoupled from the AM-managed cleanup lifecycle
11643     */
11644    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11645            ApplicationErrorReport.CrashInfo crashInfo) {
11646        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11647                UserHandle.getUserId(Binder.getCallingUid()), processName,
11648                r == null ? -1 : r.info.flags,
11649                crashInfo.exceptionClassName,
11650                crashInfo.exceptionMessage,
11651                crashInfo.throwFileName,
11652                crashInfo.throwLineNumber);
11653
11654        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11655
11656        crashApplication(r, crashInfo);
11657    }
11658
11659    public void handleApplicationStrictModeViolation(
11660            IBinder app,
11661            int violationMask,
11662            StrictMode.ViolationInfo info) {
11663        ProcessRecord r = findAppProcess(app, "StrictMode");
11664        if (r == null) {
11665            return;
11666        }
11667
11668        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11669            Integer stackFingerprint = info.hashCode();
11670            boolean logIt = true;
11671            synchronized (mAlreadyLoggedViolatedStacks) {
11672                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11673                    logIt = false;
11674                    // TODO: sub-sample into EventLog for these, with
11675                    // the info.durationMillis?  Then we'd get
11676                    // the relative pain numbers, without logging all
11677                    // the stack traces repeatedly.  We'd want to do
11678                    // likewise in the client code, which also does
11679                    // dup suppression, before the Binder call.
11680                } else {
11681                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11682                        mAlreadyLoggedViolatedStacks.clear();
11683                    }
11684                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11685                }
11686            }
11687            if (logIt) {
11688                logStrictModeViolationToDropBox(r, info);
11689            }
11690        }
11691
11692        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11693            AppErrorResult result = new AppErrorResult();
11694            synchronized (this) {
11695                final long origId = Binder.clearCallingIdentity();
11696
11697                Message msg = Message.obtain();
11698                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11699                HashMap<String, Object> data = new HashMap<String, Object>();
11700                data.put("result", result);
11701                data.put("app", r);
11702                data.put("violationMask", violationMask);
11703                data.put("info", info);
11704                msg.obj = data;
11705                mHandler.sendMessage(msg);
11706
11707                Binder.restoreCallingIdentity(origId);
11708            }
11709            int res = result.get();
11710            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11711        }
11712    }
11713
11714    // Depending on the policy in effect, there could be a bunch of
11715    // these in quick succession so we try to batch these together to
11716    // minimize disk writes, number of dropbox entries, and maximize
11717    // compression, by having more fewer, larger records.
11718    private void logStrictModeViolationToDropBox(
11719            ProcessRecord process,
11720            StrictMode.ViolationInfo info) {
11721        if (info == null) {
11722            return;
11723        }
11724        final boolean isSystemApp = process == null ||
11725                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11726                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11727        final String processName = process == null ? "unknown" : process.processName;
11728        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11729        final DropBoxManager dbox = (DropBoxManager)
11730                mContext.getSystemService(Context.DROPBOX_SERVICE);
11731
11732        // Exit early if the dropbox isn't configured to accept this report type.
11733        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11734
11735        boolean bufferWasEmpty;
11736        boolean needsFlush;
11737        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11738        synchronized (sb) {
11739            bufferWasEmpty = sb.length() == 0;
11740            appendDropBoxProcessHeaders(process, processName, sb);
11741            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11742            sb.append("System-App: ").append(isSystemApp).append("\n");
11743            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11744            if (info.violationNumThisLoop != 0) {
11745                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11746            }
11747            if (info.numAnimationsRunning != 0) {
11748                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11749            }
11750            if (info.broadcastIntentAction != null) {
11751                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11752            }
11753            if (info.durationMillis != -1) {
11754                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11755            }
11756            if (info.numInstances != -1) {
11757                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11758            }
11759            if (info.tags != null) {
11760                for (String tag : info.tags) {
11761                    sb.append("Span-Tag: ").append(tag).append("\n");
11762                }
11763            }
11764            sb.append("\n");
11765            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11766                sb.append(info.crashInfo.stackTrace);
11767                sb.append("\n");
11768            }
11769            if (info.message != null) {
11770                sb.append(info.message);
11771                sb.append("\n");
11772            }
11773
11774            // Only buffer up to ~64k.  Various logging bits truncate
11775            // things at 128k.
11776            needsFlush = (sb.length() > 64 * 1024);
11777        }
11778
11779        // Flush immediately if the buffer's grown too large, or this
11780        // is a non-system app.  Non-system apps are isolated with a
11781        // different tag & policy and not batched.
11782        //
11783        // Batching is useful during internal testing with
11784        // StrictMode settings turned up high.  Without batching,
11785        // thousands of separate files could be created on boot.
11786        if (!isSystemApp || needsFlush) {
11787            new Thread("Error dump: " + dropboxTag) {
11788                @Override
11789                public void run() {
11790                    String report;
11791                    synchronized (sb) {
11792                        report = sb.toString();
11793                        sb.delete(0, sb.length());
11794                        sb.trimToSize();
11795                    }
11796                    if (report.length() != 0) {
11797                        dbox.addText(dropboxTag, report);
11798                    }
11799                }
11800            }.start();
11801            return;
11802        }
11803
11804        // System app batching:
11805        if (!bufferWasEmpty) {
11806            // An existing dropbox-writing thread is outstanding, so
11807            // we don't need to start it up.  The existing thread will
11808            // catch the buffer appends we just did.
11809            return;
11810        }
11811
11812        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11813        // (After this point, we shouldn't access AMS internal data structures.)
11814        new Thread("Error dump: " + dropboxTag) {
11815            @Override
11816            public void run() {
11817                // 5 second sleep to let stacks arrive and be batched together
11818                try {
11819                    Thread.sleep(5000);  // 5 seconds
11820                } catch (InterruptedException e) {}
11821
11822                String errorReport;
11823                synchronized (mStrictModeBuffer) {
11824                    errorReport = mStrictModeBuffer.toString();
11825                    if (errorReport.length() == 0) {
11826                        return;
11827                    }
11828                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11829                    mStrictModeBuffer.trimToSize();
11830                }
11831                dbox.addText(dropboxTag, errorReport);
11832            }
11833        }.start();
11834    }
11835
11836    /**
11837     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11838     * @param app object of the crashing app, null for the system server
11839     * @param tag reported by the caller
11840     * @param system whether this wtf is coming from the system
11841     * @param crashInfo describing the context of the error
11842     * @return true if the process should exit immediately (WTF is fatal)
11843     */
11844    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11845            final ApplicationErrorReport.CrashInfo crashInfo) {
11846        final int callingUid = Binder.getCallingUid();
11847        final int callingPid = Binder.getCallingPid();
11848
11849        if (system) {
11850            // If this is coming from the system, we could very well have low-level
11851            // system locks held, so we want to do this all asynchronously.  And we
11852            // never want this to become fatal, so there is that too.
11853            mHandler.post(new Runnable() {
11854                @Override public void run() {
11855                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11856                }
11857            });
11858            return false;
11859        }
11860
11861        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11862                crashInfo);
11863
11864        if (r != null && r.pid != Process.myPid() &&
11865                Settings.Global.getInt(mContext.getContentResolver(),
11866                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11867            crashApplication(r, crashInfo);
11868            return true;
11869        } else {
11870            return false;
11871        }
11872    }
11873
11874    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11875            final ApplicationErrorReport.CrashInfo crashInfo) {
11876        final ProcessRecord r = findAppProcess(app, "WTF");
11877        final String processName = app == null ? "system_server"
11878                : (r == null ? "unknown" : r.processName);
11879
11880        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11881                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11882
11883        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11884
11885        return r;
11886    }
11887
11888    /**
11889     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11890     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11891     */
11892    private ProcessRecord findAppProcess(IBinder app, String reason) {
11893        if (app == null) {
11894            return null;
11895        }
11896
11897        synchronized (this) {
11898            final int NP = mProcessNames.getMap().size();
11899            for (int ip=0; ip<NP; ip++) {
11900                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11901                final int NA = apps.size();
11902                for (int ia=0; ia<NA; ia++) {
11903                    ProcessRecord p = apps.valueAt(ia);
11904                    if (p.thread != null && p.thread.asBinder() == app) {
11905                        return p;
11906                    }
11907                }
11908            }
11909
11910            Slog.w(TAG, "Can't find mystery application for " + reason
11911                    + " from pid=" + Binder.getCallingPid()
11912                    + " uid=" + Binder.getCallingUid() + ": " + app);
11913            return null;
11914        }
11915    }
11916
11917    /**
11918     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11919     * to append various headers to the dropbox log text.
11920     */
11921    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11922            StringBuilder sb) {
11923        // Watchdog thread ends up invoking this function (with
11924        // a null ProcessRecord) to add the stack file to dropbox.
11925        // Do not acquire a lock on this (am) in such cases, as it
11926        // could cause a potential deadlock, if and when watchdog
11927        // is invoked due to unavailability of lock on am and it
11928        // would prevent watchdog from killing system_server.
11929        if (process == null) {
11930            sb.append("Process: ").append(processName).append("\n");
11931            return;
11932        }
11933        // Note: ProcessRecord 'process' is guarded by the service
11934        // instance.  (notably process.pkgList, which could otherwise change
11935        // concurrently during execution of this method)
11936        synchronized (this) {
11937            sb.append("Process: ").append(processName).append("\n");
11938            int flags = process.info.flags;
11939            IPackageManager pm = AppGlobals.getPackageManager();
11940            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11941            for (int ip=0; ip<process.pkgList.size(); ip++) {
11942                String pkg = process.pkgList.keyAt(ip);
11943                sb.append("Package: ").append(pkg);
11944                try {
11945                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11946                    if (pi != null) {
11947                        sb.append(" v").append(pi.versionCode);
11948                        if (pi.versionName != null) {
11949                            sb.append(" (").append(pi.versionName).append(")");
11950                        }
11951                    }
11952                } catch (RemoteException e) {
11953                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11954                }
11955                sb.append("\n");
11956            }
11957        }
11958    }
11959
11960    private static String processClass(ProcessRecord process) {
11961        if (process == null || process.pid == MY_PID) {
11962            return "system_server";
11963        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11964            return "system_app";
11965        } else {
11966            return "data_app";
11967        }
11968    }
11969
11970    /**
11971     * Write a description of an error (crash, WTF, ANR) to the drop box.
11972     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11973     * @param process which caused the error, null means the system server
11974     * @param activity which triggered the error, null if unknown
11975     * @param parent activity related to the error, null if unknown
11976     * @param subject line related to the error, null if absent
11977     * @param report in long form describing the error, null if absent
11978     * @param logFile to include in the report, null if none
11979     * @param crashInfo giving an application stack trace, null if absent
11980     */
11981    public void addErrorToDropBox(String eventType,
11982            ProcessRecord process, String processName, ActivityRecord activity,
11983            ActivityRecord parent, String subject,
11984            final String report, final File logFile,
11985            final ApplicationErrorReport.CrashInfo crashInfo) {
11986        // NOTE -- this must never acquire the ActivityManagerService lock,
11987        // otherwise the watchdog may be prevented from resetting the system.
11988
11989        final String dropboxTag = processClass(process) + "_" + eventType;
11990        final DropBoxManager dbox = (DropBoxManager)
11991                mContext.getSystemService(Context.DROPBOX_SERVICE);
11992
11993        // Exit early if the dropbox isn't configured to accept this report type.
11994        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11995
11996        final StringBuilder sb = new StringBuilder(1024);
11997        appendDropBoxProcessHeaders(process, processName, sb);
11998        if (activity != null) {
11999            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12000        }
12001        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12002            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12003        }
12004        if (parent != null && parent != activity) {
12005            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12006        }
12007        if (subject != null) {
12008            sb.append("Subject: ").append(subject).append("\n");
12009        }
12010        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12011        if (Debug.isDebuggerConnected()) {
12012            sb.append("Debugger: Connected\n");
12013        }
12014        sb.append("\n");
12015
12016        // Do the rest in a worker thread to avoid blocking the caller on I/O
12017        // (After this point, we shouldn't access AMS internal data structures.)
12018        Thread worker = new Thread("Error dump: " + dropboxTag) {
12019            @Override
12020            public void run() {
12021                if (report != null) {
12022                    sb.append(report);
12023                }
12024                if (logFile != null) {
12025                    try {
12026                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12027                                    "\n\n[[TRUNCATED]]"));
12028                    } catch (IOException e) {
12029                        Slog.e(TAG, "Error reading " + logFile, e);
12030                    }
12031                }
12032                if (crashInfo != null && crashInfo.stackTrace != null) {
12033                    sb.append(crashInfo.stackTrace);
12034                }
12035
12036                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12037                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12038                if (lines > 0) {
12039                    sb.append("\n");
12040
12041                    // Merge several logcat streams, and take the last N lines
12042                    InputStreamReader input = null;
12043                    try {
12044                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12045                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12046                                "-b", "crash",
12047                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12048
12049                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12050                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12051                        input = new InputStreamReader(logcat.getInputStream());
12052
12053                        int num;
12054                        char[] buf = new char[8192];
12055                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12056                    } catch (IOException e) {
12057                        Slog.e(TAG, "Error running logcat", e);
12058                    } finally {
12059                        if (input != null) try { input.close(); } catch (IOException e) {}
12060                    }
12061                }
12062
12063                dbox.addText(dropboxTag, sb.toString());
12064            }
12065        };
12066
12067        if (process == null) {
12068            // If process is null, we are being called from some internal code
12069            // and may be about to die -- run this synchronously.
12070            worker.run();
12071        } else {
12072            worker.start();
12073        }
12074    }
12075
12076    /**
12077     * Bring up the "unexpected error" dialog box for a crashing app.
12078     * Deal with edge cases (intercepts from instrumented applications,
12079     * ActivityController, error intent receivers, that sort of thing).
12080     * @param r the application crashing
12081     * @param crashInfo describing the failure
12082     */
12083    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12084        long timeMillis = System.currentTimeMillis();
12085        String shortMsg = crashInfo.exceptionClassName;
12086        String longMsg = crashInfo.exceptionMessage;
12087        String stackTrace = crashInfo.stackTrace;
12088        if (shortMsg != null && longMsg != null) {
12089            longMsg = shortMsg + ": " + longMsg;
12090        } else if (shortMsg != null) {
12091            longMsg = shortMsg;
12092        }
12093
12094        AppErrorResult result = new AppErrorResult();
12095        synchronized (this) {
12096            if (mController != null) {
12097                try {
12098                    String name = r != null ? r.processName : null;
12099                    int pid = r != null ? r.pid : Binder.getCallingPid();
12100                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12101                    if (!mController.appCrashed(name, pid,
12102                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12103                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12104                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12105                            Slog.w(TAG, "Skip killing native crashed app " + name
12106                                    + "(" + pid + ") during testing");
12107                        } else {
12108                            Slog.w(TAG, "Force-killing crashed app " + name
12109                                    + " at watcher's request");
12110                            if (r != null) {
12111                                r.kill("crash", true);
12112                            } else {
12113                                // Huh.
12114                                Process.killProcess(pid);
12115                                Process.killProcessGroup(uid, pid);
12116                            }
12117                        }
12118                        return;
12119                    }
12120                } catch (RemoteException e) {
12121                    mController = null;
12122                    Watchdog.getInstance().setActivityController(null);
12123                }
12124            }
12125
12126            final long origId = Binder.clearCallingIdentity();
12127
12128            // If this process is running instrumentation, finish it.
12129            if (r != null && r.instrumentationClass != null) {
12130                Slog.w(TAG, "Error in app " + r.processName
12131                      + " running instrumentation " + r.instrumentationClass + ":");
12132                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12133                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12134                Bundle info = new Bundle();
12135                info.putString("shortMsg", shortMsg);
12136                info.putString("longMsg", longMsg);
12137                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12138                Binder.restoreCallingIdentity(origId);
12139                return;
12140            }
12141
12142            // Log crash in battery stats.
12143            if (r != null) {
12144                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12145            }
12146
12147            // If we can't identify the process or it's already exceeded its crash quota,
12148            // quit right away without showing a crash dialog.
12149            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12150                Binder.restoreCallingIdentity(origId);
12151                return;
12152            }
12153
12154            Message msg = Message.obtain();
12155            msg.what = SHOW_ERROR_MSG;
12156            HashMap data = new HashMap();
12157            data.put("result", result);
12158            data.put("app", r);
12159            msg.obj = data;
12160            mHandler.sendMessage(msg);
12161
12162            Binder.restoreCallingIdentity(origId);
12163        }
12164
12165        int res = result.get();
12166
12167        Intent appErrorIntent = null;
12168        synchronized (this) {
12169            if (r != null && !r.isolated) {
12170                // XXX Can't keep track of crash time for isolated processes,
12171                // since they don't have a persistent identity.
12172                mProcessCrashTimes.put(r.info.processName, r.uid,
12173                        SystemClock.uptimeMillis());
12174            }
12175            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12176                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12177            }
12178        }
12179
12180        if (appErrorIntent != null) {
12181            try {
12182                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12183            } catch (ActivityNotFoundException e) {
12184                Slog.w(TAG, "bug report receiver dissappeared", e);
12185            }
12186        }
12187    }
12188
12189    Intent createAppErrorIntentLocked(ProcessRecord r,
12190            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12191        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12192        if (report == null) {
12193            return null;
12194        }
12195        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12196        result.setComponent(r.errorReportReceiver);
12197        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12198        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12199        return result;
12200    }
12201
12202    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12203            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12204        if (r.errorReportReceiver == null) {
12205            return null;
12206        }
12207
12208        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12209            return null;
12210        }
12211
12212        ApplicationErrorReport report = new ApplicationErrorReport();
12213        report.packageName = r.info.packageName;
12214        report.installerPackageName = r.errorReportReceiver.getPackageName();
12215        report.processName = r.processName;
12216        report.time = timeMillis;
12217        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12218
12219        if (r.crashing || r.forceCrashReport) {
12220            report.type = ApplicationErrorReport.TYPE_CRASH;
12221            report.crashInfo = crashInfo;
12222        } else if (r.notResponding) {
12223            report.type = ApplicationErrorReport.TYPE_ANR;
12224            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12225
12226            report.anrInfo.activity = r.notRespondingReport.tag;
12227            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12228            report.anrInfo.info = r.notRespondingReport.longMsg;
12229        }
12230
12231        return report;
12232    }
12233
12234    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12235        enforceNotIsolatedCaller("getProcessesInErrorState");
12236        // assume our apps are happy - lazy create the list
12237        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12238
12239        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12240                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12241        int userId = UserHandle.getUserId(Binder.getCallingUid());
12242
12243        synchronized (this) {
12244
12245            // iterate across all processes
12246            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12247                ProcessRecord app = mLruProcesses.get(i);
12248                if (!allUsers && app.userId != userId) {
12249                    continue;
12250                }
12251                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12252                    // This one's in trouble, so we'll generate a report for it
12253                    // crashes are higher priority (in case there's a crash *and* an anr)
12254                    ActivityManager.ProcessErrorStateInfo report = null;
12255                    if (app.crashing) {
12256                        report = app.crashingReport;
12257                    } else if (app.notResponding) {
12258                        report = app.notRespondingReport;
12259                    }
12260
12261                    if (report != null) {
12262                        if (errList == null) {
12263                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12264                        }
12265                        errList.add(report);
12266                    } else {
12267                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12268                                " crashing = " + app.crashing +
12269                                " notResponding = " + app.notResponding);
12270                    }
12271                }
12272            }
12273        }
12274
12275        return errList;
12276    }
12277
12278    static int procStateToImportance(int procState, int memAdj,
12279            ActivityManager.RunningAppProcessInfo currApp) {
12280        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12281        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12282            currApp.lru = memAdj;
12283        } else {
12284            currApp.lru = 0;
12285        }
12286        return imp;
12287    }
12288
12289    private void fillInProcMemInfo(ProcessRecord app,
12290            ActivityManager.RunningAppProcessInfo outInfo) {
12291        outInfo.pid = app.pid;
12292        outInfo.uid = app.info.uid;
12293        if (mHeavyWeightProcess == app) {
12294            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12295        }
12296        if (app.persistent) {
12297            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12298        }
12299        if (app.activities.size() > 0) {
12300            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12301        }
12302        outInfo.lastTrimLevel = app.trimMemoryLevel;
12303        int adj = app.curAdj;
12304        int procState = app.curProcState;
12305        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12306        outInfo.importanceReasonCode = app.adjTypeCode;
12307        outInfo.processState = app.curProcState;
12308    }
12309
12310    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12311        enforceNotIsolatedCaller("getRunningAppProcesses");
12312        // Lazy instantiation of list
12313        List<ActivityManager.RunningAppProcessInfo> runList = null;
12314        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12315                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12316        int userId = UserHandle.getUserId(Binder.getCallingUid());
12317        synchronized (this) {
12318            // Iterate across all processes
12319            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12320                ProcessRecord app = mLruProcesses.get(i);
12321                if (!allUsers && app.userId != userId) {
12322                    continue;
12323                }
12324                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12325                    // Generate process state info for running application
12326                    ActivityManager.RunningAppProcessInfo currApp =
12327                        new ActivityManager.RunningAppProcessInfo(app.processName,
12328                                app.pid, app.getPackageList());
12329                    fillInProcMemInfo(app, currApp);
12330                    if (app.adjSource instanceof ProcessRecord) {
12331                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12332                        currApp.importanceReasonImportance =
12333                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12334                                        app.adjSourceProcState);
12335                    } else if (app.adjSource instanceof ActivityRecord) {
12336                        ActivityRecord r = (ActivityRecord)app.adjSource;
12337                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12338                    }
12339                    if (app.adjTarget instanceof ComponentName) {
12340                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12341                    }
12342                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12343                    //        + " lru=" + currApp.lru);
12344                    if (runList == null) {
12345                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12346                    }
12347                    runList.add(currApp);
12348                }
12349            }
12350        }
12351        return runList;
12352    }
12353
12354    public List<ApplicationInfo> getRunningExternalApplications() {
12355        enforceNotIsolatedCaller("getRunningExternalApplications");
12356        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12357        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12358        if (runningApps != null && runningApps.size() > 0) {
12359            Set<String> extList = new HashSet<String>();
12360            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12361                if (app.pkgList != null) {
12362                    for (String pkg : app.pkgList) {
12363                        extList.add(pkg);
12364                    }
12365                }
12366            }
12367            IPackageManager pm = AppGlobals.getPackageManager();
12368            for (String pkg : extList) {
12369                try {
12370                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12371                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12372                        retList.add(info);
12373                    }
12374                } catch (RemoteException e) {
12375                }
12376            }
12377        }
12378        return retList;
12379    }
12380
12381    @Override
12382    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12383        enforceNotIsolatedCaller("getMyMemoryState");
12384        synchronized (this) {
12385            ProcessRecord proc;
12386            synchronized (mPidsSelfLocked) {
12387                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12388            }
12389            fillInProcMemInfo(proc, outInfo);
12390        }
12391    }
12392
12393    @Override
12394    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12395        if (checkCallingPermission(android.Manifest.permission.DUMP)
12396                != PackageManager.PERMISSION_GRANTED) {
12397            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12398                    + Binder.getCallingPid()
12399                    + ", uid=" + Binder.getCallingUid()
12400                    + " without permission "
12401                    + android.Manifest.permission.DUMP);
12402            return;
12403        }
12404
12405        boolean dumpAll = false;
12406        boolean dumpClient = false;
12407        String dumpPackage = null;
12408
12409        int opti = 0;
12410        while (opti < args.length) {
12411            String opt = args[opti];
12412            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12413                break;
12414            }
12415            opti++;
12416            if ("-a".equals(opt)) {
12417                dumpAll = true;
12418            } else if ("-c".equals(opt)) {
12419                dumpClient = true;
12420            } else if ("-p".equals(opt)) {
12421                if (opti < args.length) {
12422                    dumpPackage = args[opti];
12423                    opti++;
12424                } else {
12425                    pw.println("Error: -p option requires package argument");
12426                    return;
12427                }
12428                dumpClient = true;
12429            } else if ("-h".equals(opt)) {
12430                pw.println("Activity manager dump options:");
12431                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12432                pw.println("  cmd may be one of:");
12433                pw.println("    a[ctivities]: activity stack state");
12434                pw.println("    r[recents]: recent activities state");
12435                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12436                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12437                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12438                pw.println("    o[om]: out of memory management");
12439                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12440                pw.println("    provider [COMP_SPEC]: provider client-side state");
12441                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12442                pw.println("    as[sociations]: tracked app associations");
12443                pw.println("    service [COMP_SPEC]: service client-side state");
12444                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12445                pw.println("    all: dump all activities");
12446                pw.println("    top: dump the top activity");
12447                pw.println("    write: write all pending state to storage");
12448                pw.println("    track-associations: enable association tracking");
12449                pw.println("    untrack-associations: disable and clear association tracking");
12450                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12451                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12452                pw.println("    a partial substring in a component name, a");
12453                pw.println("    hex object identifier.");
12454                pw.println("  -a: include all available server state.");
12455                pw.println("  -c: include client state.");
12456                pw.println("  -p: limit output to given package.");
12457                return;
12458            } else {
12459                pw.println("Unknown argument: " + opt + "; use -h for help");
12460            }
12461        }
12462
12463        long origId = Binder.clearCallingIdentity();
12464        boolean more = false;
12465        // Is the caller requesting to dump a particular piece of data?
12466        if (opti < args.length) {
12467            String cmd = args[opti];
12468            opti++;
12469            if ("activities".equals(cmd) || "a".equals(cmd)) {
12470                synchronized (this) {
12471                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12472                }
12473            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12474                synchronized (this) {
12475                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12476                }
12477            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12478                String[] newArgs;
12479                String name;
12480                if (opti >= args.length) {
12481                    name = null;
12482                    newArgs = EMPTY_STRING_ARRAY;
12483                } else {
12484                    dumpPackage = args[opti];
12485                    opti++;
12486                    newArgs = new String[args.length - opti];
12487                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12488                            args.length - opti);
12489                }
12490                synchronized (this) {
12491                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12492                }
12493            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12494                String[] newArgs;
12495                String name;
12496                if (opti >= args.length) {
12497                    name = null;
12498                    newArgs = EMPTY_STRING_ARRAY;
12499                } else {
12500                    dumpPackage = args[opti];
12501                    opti++;
12502                    newArgs = new String[args.length - opti];
12503                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12504                            args.length - opti);
12505                }
12506                synchronized (this) {
12507                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12508                }
12509            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12510                String[] newArgs;
12511                String name;
12512                if (opti >= args.length) {
12513                    name = null;
12514                    newArgs = EMPTY_STRING_ARRAY;
12515                } else {
12516                    dumpPackage = args[opti];
12517                    opti++;
12518                    newArgs = new String[args.length - opti];
12519                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12520                            args.length - opti);
12521                }
12522                synchronized (this) {
12523                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12524                }
12525            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12526                synchronized (this) {
12527                    dumpOomLocked(fd, pw, args, opti, true);
12528                }
12529            } else if ("provider".equals(cmd)) {
12530                String[] newArgs;
12531                String name;
12532                if (opti >= args.length) {
12533                    name = null;
12534                    newArgs = EMPTY_STRING_ARRAY;
12535                } else {
12536                    name = args[opti];
12537                    opti++;
12538                    newArgs = new String[args.length - opti];
12539                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12540                }
12541                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12542                    pw.println("No providers match: " + name);
12543                    pw.println("Use -h for help.");
12544                }
12545            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12546                synchronized (this) {
12547                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12548                }
12549            } else if ("service".equals(cmd)) {
12550                String[] newArgs;
12551                String name;
12552                if (opti >= args.length) {
12553                    name = null;
12554                    newArgs = EMPTY_STRING_ARRAY;
12555                } else {
12556                    name = args[opti];
12557                    opti++;
12558                    newArgs = new String[args.length - opti];
12559                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12560                            args.length - opti);
12561                }
12562                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12563                    pw.println("No services match: " + name);
12564                    pw.println("Use -h for help.");
12565                }
12566            } else if ("package".equals(cmd)) {
12567                String[] newArgs;
12568                if (opti >= args.length) {
12569                    pw.println("package: no package name specified");
12570                    pw.println("Use -h for help.");
12571                } else {
12572                    dumpPackage = args[opti];
12573                    opti++;
12574                    newArgs = new String[args.length - opti];
12575                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12576                            args.length - opti);
12577                    args = newArgs;
12578                    opti = 0;
12579                    more = true;
12580                }
12581            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12582                synchronized (this) {
12583                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12584                }
12585            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12586                synchronized (this) {
12587                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12588                }
12589            } else if ("write".equals(cmd)) {
12590                mTaskPersister.flush();
12591                pw.println("All tasks persisted.");
12592                return;
12593            } else if ("track-associations".equals(cmd)) {
12594                synchronized (this) {
12595                    if (!mTrackingAssociations) {
12596                        mTrackingAssociations = true;
12597                        pw.println("Association tracking started.");
12598                    } else {
12599                        pw.println("Association tracking already enabled.");
12600                    }
12601                }
12602                return;
12603            } else if ("untrack-associations".equals(cmd)) {
12604                synchronized (this) {
12605                    if (mTrackingAssociations) {
12606                        mTrackingAssociations = false;
12607                        mAssociations.clear();
12608                        pw.println("Association tracking stopped.");
12609                    } else {
12610                        pw.println("Association tracking not running.");
12611                    }
12612                }
12613                return;
12614            } else {
12615                // Dumping a single activity?
12616                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12617                    pw.println("Bad activity command, or no activities match: " + cmd);
12618                    pw.println("Use -h for help.");
12619                }
12620            }
12621            if (!more) {
12622                Binder.restoreCallingIdentity(origId);
12623                return;
12624            }
12625        }
12626
12627        // No piece of data specified, dump everything.
12628        synchronized (this) {
12629            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12630            pw.println();
12631            if (dumpAll) {
12632                pw.println("-------------------------------------------------------------------------------");
12633            }
12634            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12635            pw.println();
12636            if (dumpAll) {
12637                pw.println("-------------------------------------------------------------------------------");
12638            }
12639            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12640            pw.println();
12641            if (dumpAll) {
12642                pw.println("-------------------------------------------------------------------------------");
12643            }
12644            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12645            pw.println();
12646            if (dumpAll) {
12647                pw.println("-------------------------------------------------------------------------------");
12648            }
12649            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12650            pw.println();
12651            if (dumpAll) {
12652                pw.println("-------------------------------------------------------------------------------");
12653            }
12654            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12655            if (mAssociations.size() > 0) {
12656                pw.println();
12657                if (dumpAll) {
12658                    pw.println("-------------------------------------------------------------------------------");
12659                }
12660                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12661            }
12662            pw.println();
12663            if (dumpAll) {
12664                pw.println("-------------------------------------------------------------------------------");
12665            }
12666            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12667        }
12668        Binder.restoreCallingIdentity(origId);
12669    }
12670
12671    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12672            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12673        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12674
12675        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12676                dumpPackage);
12677        boolean needSep = printedAnything;
12678
12679        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12680                dumpPackage, needSep, "  mFocusedActivity: ");
12681        if (printed) {
12682            printedAnything = true;
12683            needSep = false;
12684        }
12685
12686        if (dumpPackage == null) {
12687            if (needSep) {
12688                pw.println();
12689            }
12690            needSep = true;
12691            printedAnything = true;
12692            mStackSupervisor.dump(pw, "  ");
12693        }
12694
12695        if (!printedAnything) {
12696            pw.println("  (nothing)");
12697        }
12698    }
12699
12700    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12701            int opti, boolean dumpAll, String dumpPackage) {
12702        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12703
12704        boolean printedAnything = false;
12705
12706        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12707            boolean printedHeader = false;
12708
12709            final int N = mRecentTasks.size();
12710            for (int i=0; i<N; i++) {
12711                TaskRecord tr = mRecentTasks.get(i);
12712                if (dumpPackage != null) {
12713                    if (tr.realActivity == null ||
12714                            !dumpPackage.equals(tr.realActivity)) {
12715                        continue;
12716                    }
12717                }
12718                if (!printedHeader) {
12719                    pw.println("  Recent tasks:");
12720                    printedHeader = true;
12721                    printedAnything = true;
12722                }
12723                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12724                        pw.println(tr);
12725                if (dumpAll) {
12726                    mRecentTasks.get(i).dump(pw, "    ");
12727                }
12728            }
12729        }
12730
12731        if (!printedAnything) {
12732            pw.println("  (nothing)");
12733        }
12734    }
12735
12736    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12737            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12738        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12739
12740        int dumpUid = 0;
12741        if (dumpPackage != null) {
12742            IPackageManager pm = AppGlobals.getPackageManager();
12743            try {
12744                dumpUid = pm.getPackageUid(dumpPackage, 0);
12745            } catch (RemoteException e) {
12746            }
12747        }
12748
12749        boolean printedAnything = false;
12750
12751        final long now = SystemClock.uptimeMillis();
12752
12753        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12754            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12755                    = mAssociations.valueAt(i1);
12756            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12757                SparseArray<ArrayMap<String, Association>> sourceUids
12758                        = targetComponents.valueAt(i2);
12759                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12760                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12761                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12762                        Association ass = sourceProcesses.valueAt(i4);
12763                        if (dumpPackage != null) {
12764                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12765                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12766                                continue;
12767                            }
12768                        }
12769                        printedAnything = true;
12770                        pw.print("  ");
12771                        pw.print(ass.mTargetProcess);
12772                        pw.print("/");
12773                        UserHandle.formatUid(pw, ass.mTargetUid);
12774                        pw.print(" <- ");
12775                        pw.print(ass.mSourceProcess);
12776                        pw.print("/");
12777                        UserHandle.formatUid(pw, ass.mSourceUid);
12778                        pw.println();
12779                        pw.print("    via ");
12780                        pw.print(ass.mTargetComponent.flattenToShortString());
12781                        pw.println();
12782                        pw.print("    ");
12783                        long dur = ass.mTime;
12784                        if (ass.mNesting > 0) {
12785                            dur += now - ass.mStartTime;
12786                        }
12787                        TimeUtils.formatDuration(dur, pw);
12788                        pw.print(" (");
12789                        pw.print(ass.mCount);
12790                        pw.println(" times)");
12791                        if (ass.mNesting > 0) {
12792                            pw.print("    ");
12793                            pw.print(" Currently active: ");
12794                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12795                            pw.println();
12796                        }
12797                    }
12798                }
12799            }
12800
12801        }
12802
12803        if (!printedAnything) {
12804            pw.println("  (nothing)");
12805        }
12806    }
12807
12808    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12809            int opti, boolean dumpAll, String dumpPackage) {
12810        boolean needSep = false;
12811        boolean printedAnything = false;
12812        int numPers = 0;
12813
12814        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12815
12816        if (dumpAll) {
12817            final int NP = mProcessNames.getMap().size();
12818            for (int ip=0; ip<NP; ip++) {
12819                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12820                final int NA = procs.size();
12821                for (int ia=0; ia<NA; ia++) {
12822                    ProcessRecord r = procs.valueAt(ia);
12823                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12824                        continue;
12825                    }
12826                    if (!needSep) {
12827                        pw.println("  All known processes:");
12828                        needSep = true;
12829                        printedAnything = true;
12830                    }
12831                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12832                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12833                        pw.print(" "); pw.println(r);
12834                    r.dump(pw, "    ");
12835                    if (r.persistent) {
12836                        numPers++;
12837                    }
12838                }
12839            }
12840        }
12841
12842        if (mIsolatedProcesses.size() > 0) {
12843            boolean printed = false;
12844            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12845                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12846                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12847                    continue;
12848                }
12849                if (!printed) {
12850                    if (needSep) {
12851                        pw.println();
12852                    }
12853                    pw.println("  Isolated process list (sorted by uid):");
12854                    printedAnything = true;
12855                    printed = true;
12856                    needSep = true;
12857                }
12858                pw.println(String.format("%sIsolated #%2d: %s",
12859                        "    ", i, r.toString()));
12860            }
12861        }
12862
12863        if (mLruProcesses.size() > 0) {
12864            if (needSep) {
12865                pw.println();
12866            }
12867            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12868                    pw.print(" total, non-act at ");
12869                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12870                    pw.print(", non-svc at ");
12871                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12872                    pw.println("):");
12873            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12874            needSep = true;
12875            printedAnything = true;
12876        }
12877
12878        if (dumpAll || dumpPackage != null) {
12879            synchronized (mPidsSelfLocked) {
12880                boolean printed = false;
12881                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12882                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12883                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12884                        continue;
12885                    }
12886                    if (!printed) {
12887                        if (needSep) pw.println();
12888                        needSep = true;
12889                        pw.println("  PID mappings:");
12890                        printed = true;
12891                        printedAnything = true;
12892                    }
12893                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12894                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12895                }
12896            }
12897        }
12898
12899        if (mForegroundProcesses.size() > 0) {
12900            synchronized (mPidsSelfLocked) {
12901                boolean printed = false;
12902                for (int i=0; i<mForegroundProcesses.size(); i++) {
12903                    ProcessRecord r = mPidsSelfLocked.get(
12904                            mForegroundProcesses.valueAt(i).pid);
12905                    if (dumpPackage != null && (r == null
12906                            || !r.pkgList.containsKey(dumpPackage))) {
12907                        continue;
12908                    }
12909                    if (!printed) {
12910                        if (needSep) pw.println();
12911                        needSep = true;
12912                        pw.println("  Foreground Processes:");
12913                        printed = true;
12914                        printedAnything = true;
12915                    }
12916                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12917                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12918                }
12919            }
12920        }
12921
12922        if (mPersistentStartingProcesses.size() > 0) {
12923            if (needSep) pw.println();
12924            needSep = true;
12925            printedAnything = true;
12926            pw.println("  Persisent processes that are starting:");
12927            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12928                    "Starting Norm", "Restarting PERS", dumpPackage);
12929        }
12930
12931        if (mRemovedProcesses.size() > 0) {
12932            if (needSep) pw.println();
12933            needSep = true;
12934            printedAnything = true;
12935            pw.println("  Processes that are being removed:");
12936            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12937                    "Removed Norm", "Removed PERS", dumpPackage);
12938        }
12939
12940        if (mProcessesOnHold.size() > 0) {
12941            if (needSep) pw.println();
12942            needSep = true;
12943            printedAnything = true;
12944            pw.println("  Processes that are on old until the system is ready:");
12945            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12946                    "OnHold Norm", "OnHold PERS", dumpPackage);
12947        }
12948
12949        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12950
12951        if (mProcessCrashTimes.getMap().size() > 0) {
12952            boolean printed = false;
12953            long now = SystemClock.uptimeMillis();
12954            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12955            final int NP = pmap.size();
12956            for (int ip=0; ip<NP; ip++) {
12957                String pname = pmap.keyAt(ip);
12958                SparseArray<Long> uids = pmap.valueAt(ip);
12959                final int N = uids.size();
12960                for (int i=0; i<N; i++) {
12961                    int puid = uids.keyAt(i);
12962                    ProcessRecord r = mProcessNames.get(pname, puid);
12963                    if (dumpPackage != null && (r == null
12964                            || !r.pkgList.containsKey(dumpPackage))) {
12965                        continue;
12966                    }
12967                    if (!printed) {
12968                        if (needSep) pw.println();
12969                        needSep = true;
12970                        pw.println("  Time since processes crashed:");
12971                        printed = true;
12972                        printedAnything = true;
12973                    }
12974                    pw.print("    Process "); pw.print(pname);
12975                            pw.print(" uid "); pw.print(puid);
12976                            pw.print(": last crashed ");
12977                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12978                            pw.println(" ago");
12979                }
12980            }
12981        }
12982
12983        if (mBadProcesses.getMap().size() > 0) {
12984            boolean printed = false;
12985            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12986            final int NP = pmap.size();
12987            for (int ip=0; ip<NP; ip++) {
12988                String pname = pmap.keyAt(ip);
12989                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12990                final int N = uids.size();
12991                for (int i=0; i<N; i++) {
12992                    int puid = uids.keyAt(i);
12993                    ProcessRecord r = mProcessNames.get(pname, puid);
12994                    if (dumpPackage != null && (r == null
12995                            || !r.pkgList.containsKey(dumpPackage))) {
12996                        continue;
12997                    }
12998                    if (!printed) {
12999                        if (needSep) pw.println();
13000                        needSep = true;
13001                        pw.println("  Bad processes:");
13002                        printedAnything = true;
13003                    }
13004                    BadProcessInfo info = uids.valueAt(i);
13005                    pw.print("    Bad process "); pw.print(pname);
13006                            pw.print(" uid "); pw.print(puid);
13007                            pw.print(": crashed at time "); pw.println(info.time);
13008                    if (info.shortMsg != null) {
13009                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13010                    }
13011                    if (info.longMsg != null) {
13012                        pw.print("      Long msg: "); pw.println(info.longMsg);
13013                    }
13014                    if (info.stack != null) {
13015                        pw.println("      Stack:");
13016                        int lastPos = 0;
13017                        for (int pos=0; pos<info.stack.length(); pos++) {
13018                            if (info.stack.charAt(pos) == '\n') {
13019                                pw.print("        ");
13020                                pw.write(info.stack, lastPos, pos-lastPos);
13021                                pw.println();
13022                                lastPos = pos+1;
13023                            }
13024                        }
13025                        if (lastPos < info.stack.length()) {
13026                            pw.print("        ");
13027                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13028                            pw.println();
13029                        }
13030                    }
13031                }
13032            }
13033        }
13034
13035        if (dumpPackage == null) {
13036            pw.println();
13037            needSep = false;
13038            pw.println("  mStartedUsers:");
13039            for (int i=0; i<mStartedUsers.size(); i++) {
13040                UserStartedState uss = mStartedUsers.valueAt(i);
13041                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13042                        pw.print(": "); uss.dump("", pw);
13043            }
13044            pw.print("  mStartedUserArray: [");
13045            for (int i=0; i<mStartedUserArray.length; i++) {
13046                if (i > 0) pw.print(", ");
13047                pw.print(mStartedUserArray[i]);
13048            }
13049            pw.println("]");
13050            pw.print("  mUserLru: [");
13051            for (int i=0; i<mUserLru.size(); i++) {
13052                if (i > 0) pw.print(", ");
13053                pw.print(mUserLru.get(i));
13054            }
13055            pw.println("]");
13056            if (dumpAll) {
13057                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13058            }
13059            synchronized (mUserProfileGroupIdsSelfLocked) {
13060                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13061                    pw.println("  mUserProfileGroupIds:");
13062                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13063                        pw.print("    User #");
13064                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13065                        pw.print(" -> profile #");
13066                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13067                    }
13068                }
13069            }
13070        }
13071        if (mHomeProcess != null && (dumpPackage == null
13072                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13073            if (needSep) {
13074                pw.println();
13075                needSep = false;
13076            }
13077            pw.println("  mHomeProcess: " + mHomeProcess);
13078        }
13079        if (mPreviousProcess != null && (dumpPackage == null
13080                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13081            if (needSep) {
13082                pw.println();
13083                needSep = false;
13084            }
13085            pw.println("  mPreviousProcess: " + mPreviousProcess);
13086        }
13087        if (dumpAll) {
13088            StringBuilder sb = new StringBuilder(128);
13089            sb.append("  mPreviousProcessVisibleTime: ");
13090            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13091            pw.println(sb);
13092        }
13093        if (mHeavyWeightProcess != null && (dumpPackage == null
13094                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13095            if (needSep) {
13096                pw.println();
13097                needSep = false;
13098            }
13099            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13100        }
13101        if (dumpPackage == null) {
13102            pw.println("  mConfiguration: " + mConfiguration);
13103        }
13104        if (dumpAll) {
13105            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13106            if (mCompatModePackages.getPackages().size() > 0) {
13107                boolean printed = false;
13108                for (Map.Entry<String, Integer> entry
13109                        : mCompatModePackages.getPackages().entrySet()) {
13110                    String pkg = entry.getKey();
13111                    int mode = entry.getValue();
13112                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13113                        continue;
13114                    }
13115                    if (!printed) {
13116                        pw.println("  mScreenCompatPackages:");
13117                        printed = true;
13118                    }
13119                    pw.print("    "); pw.print(pkg); pw.print(": ");
13120                            pw.print(mode); pw.println();
13121                }
13122            }
13123        }
13124        if (dumpPackage == null) {
13125            pw.println("  mWakefulness="
13126                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13127            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13128                    + lockScreenShownToString());
13129            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13130                    + " mTestPssMode=" + mTestPssMode);
13131        }
13132        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13133                || mOrigWaitForDebugger) {
13134            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13135                    || dumpPackage.equals(mOrigDebugApp)) {
13136                if (needSep) {
13137                    pw.println();
13138                    needSep = false;
13139                }
13140                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13141                        + " mDebugTransient=" + mDebugTransient
13142                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13143            }
13144        }
13145        if (mOpenGlTraceApp != null) {
13146            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13147                if (needSep) {
13148                    pw.println();
13149                    needSep = false;
13150                }
13151                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13152            }
13153        }
13154        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13155                || mProfileFd != null) {
13156            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13157                if (needSep) {
13158                    pw.println();
13159                    needSep = false;
13160                }
13161                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13162                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13163                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13164                        + mAutoStopProfiler);
13165                pw.println("  mProfileType=" + mProfileType);
13166            }
13167        }
13168        if (dumpPackage == null) {
13169            if (mAlwaysFinishActivities || mController != null) {
13170                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13171                        + " mController=" + mController);
13172            }
13173            if (dumpAll) {
13174                pw.println("  Total persistent processes: " + numPers);
13175                pw.println("  mProcessesReady=" + mProcessesReady
13176                        + " mSystemReady=" + mSystemReady
13177                        + " mBooted=" + mBooted
13178                        + " mFactoryTest=" + mFactoryTest);
13179                pw.println("  mBooting=" + mBooting
13180                        + " mCallFinishBooting=" + mCallFinishBooting
13181                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13182                pw.print("  mLastPowerCheckRealtime=");
13183                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13184                        pw.println("");
13185                pw.print("  mLastPowerCheckUptime=");
13186                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13187                        pw.println("");
13188                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13189                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13190                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13191                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13192                        + " (" + mLruProcesses.size() + " total)"
13193                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13194                        + " mNumServiceProcs=" + mNumServiceProcs
13195                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13196                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13197                        + " mLastMemoryLevel" + mLastMemoryLevel
13198                        + " mLastNumProcesses" + mLastNumProcesses);
13199                long now = SystemClock.uptimeMillis();
13200                pw.print("  mLastIdleTime=");
13201                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13202                        pw.print(" mLowRamSinceLastIdle=");
13203                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13204                        pw.println();
13205            }
13206        }
13207
13208        if (!printedAnything) {
13209            pw.println("  (nothing)");
13210        }
13211    }
13212
13213    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13214            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13215        if (mProcessesToGc.size() > 0) {
13216            boolean printed = false;
13217            long now = SystemClock.uptimeMillis();
13218            for (int i=0; i<mProcessesToGc.size(); i++) {
13219                ProcessRecord proc = mProcessesToGc.get(i);
13220                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13221                    continue;
13222                }
13223                if (!printed) {
13224                    if (needSep) pw.println();
13225                    needSep = true;
13226                    pw.println("  Processes that are waiting to GC:");
13227                    printed = true;
13228                }
13229                pw.print("    Process "); pw.println(proc);
13230                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13231                        pw.print(", last gced=");
13232                        pw.print(now-proc.lastRequestedGc);
13233                        pw.print(" ms ago, last lowMem=");
13234                        pw.print(now-proc.lastLowMemory);
13235                        pw.println(" ms ago");
13236
13237            }
13238        }
13239        return needSep;
13240    }
13241
13242    void printOomLevel(PrintWriter pw, String name, int adj) {
13243        pw.print("    ");
13244        if (adj >= 0) {
13245            pw.print(' ');
13246            if (adj < 10) pw.print(' ');
13247        } else {
13248            if (adj > -10) pw.print(' ');
13249        }
13250        pw.print(adj);
13251        pw.print(": ");
13252        pw.print(name);
13253        pw.print(" (");
13254        pw.print(mProcessList.getMemLevel(adj)/1024);
13255        pw.println(" kB)");
13256    }
13257
13258    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13259            int opti, boolean dumpAll) {
13260        boolean needSep = false;
13261
13262        if (mLruProcesses.size() > 0) {
13263            if (needSep) pw.println();
13264            needSep = true;
13265            pw.println("  OOM levels:");
13266            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13267            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13268            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13269            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13270            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13271            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13272            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13273            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13274            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13275            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13276            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13277            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13278            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13279            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13280
13281            if (needSep) pw.println();
13282            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13283                    pw.print(" total, non-act at ");
13284                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13285                    pw.print(", non-svc at ");
13286                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13287                    pw.println("):");
13288            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13289            needSep = true;
13290        }
13291
13292        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13293
13294        pw.println();
13295        pw.println("  mHomeProcess: " + mHomeProcess);
13296        pw.println("  mPreviousProcess: " + mPreviousProcess);
13297        if (mHeavyWeightProcess != null) {
13298            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13299        }
13300
13301        return true;
13302    }
13303
13304    /**
13305     * There are three ways to call this:
13306     *  - no provider specified: dump all the providers
13307     *  - a flattened component name that matched an existing provider was specified as the
13308     *    first arg: dump that one provider
13309     *  - the first arg isn't the flattened component name of an existing provider:
13310     *    dump all providers whose component contains the first arg as a substring
13311     */
13312    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13313            int opti, boolean dumpAll) {
13314        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13315    }
13316
13317    static class ItemMatcher {
13318        ArrayList<ComponentName> components;
13319        ArrayList<String> strings;
13320        ArrayList<Integer> objects;
13321        boolean all;
13322
13323        ItemMatcher() {
13324            all = true;
13325        }
13326
13327        void build(String name) {
13328            ComponentName componentName = ComponentName.unflattenFromString(name);
13329            if (componentName != null) {
13330                if (components == null) {
13331                    components = new ArrayList<ComponentName>();
13332                }
13333                components.add(componentName);
13334                all = false;
13335            } else {
13336                int objectId = 0;
13337                // Not a '/' separated full component name; maybe an object ID?
13338                try {
13339                    objectId = Integer.parseInt(name, 16);
13340                    if (objects == null) {
13341                        objects = new ArrayList<Integer>();
13342                    }
13343                    objects.add(objectId);
13344                    all = false;
13345                } catch (RuntimeException e) {
13346                    // Not an integer; just do string match.
13347                    if (strings == null) {
13348                        strings = new ArrayList<String>();
13349                    }
13350                    strings.add(name);
13351                    all = false;
13352                }
13353            }
13354        }
13355
13356        int build(String[] args, int opti) {
13357            for (; opti<args.length; opti++) {
13358                String name = args[opti];
13359                if ("--".equals(name)) {
13360                    return opti+1;
13361                }
13362                build(name);
13363            }
13364            return opti;
13365        }
13366
13367        boolean match(Object object, ComponentName comp) {
13368            if (all) {
13369                return true;
13370            }
13371            if (components != null) {
13372                for (int i=0; i<components.size(); i++) {
13373                    if (components.get(i).equals(comp)) {
13374                        return true;
13375                    }
13376                }
13377            }
13378            if (objects != null) {
13379                for (int i=0; i<objects.size(); i++) {
13380                    if (System.identityHashCode(object) == objects.get(i)) {
13381                        return true;
13382                    }
13383                }
13384            }
13385            if (strings != null) {
13386                String flat = comp.flattenToString();
13387                for (int i=0; i<strings.size(); i++) {
13388                    if (flat.contains(strings.get(i))) {
13389                        return true;
13390                    }
13391                }
13392            }
13393            return false;
13394        }
13395    }
13396
13397    /**
13398     * There are three things that cmd can be:
13399     *  - a flattened component name that matches an existing activity
13400     *  - the cmd arg isn't the flattened component name of an existing activity:
13401     *    dump all activity whose component contains the cmd as a substring
13402     *  - A hex number of the ActivityRecord object instance.
13403     */
13404    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13405            int opti, boolean dumpAll) {
13406        ArrayList<ActivityRecord> activities;
13407
13408        synchronized (this) {
13409            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13410        }
13411
13412        if (activities.size() <= 0) {
13413            return false;
13414        }
13415
13416        String[] newArgs = new String[args.length - opti];
13417        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13418
13419        TaskRecord lastTask = null;
13420        boolean needSep = false;
13421        for (int i=activities.size()-1; i>=0; i--) {
13422            ActivityRecord r = activities.get(i);
13423            if (needSep) {
13424                pw.println();
13425            }
13426            needSep = true;
13427            synchronized (this) {
13428                if (lastTask != r.task) {
13429                    lastTask = r.task;
13430                    pw.print("TASK "); pw.print(lastTask.affinity);
13431                            pw.print(" id="); pw.println(lastTask.taskId);
13432                    if (dumpAll) {
13433                        lastTask.dump(pw, "  ");
13434                    }
13435                }
13436            }
13437            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13438        }
13439        return true;
13440    }
13441
13442    /**
13443     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13444     * there is a thread associated with the activity.
13445     */
13446    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13447            final ActivityRecord r, String[] args, boolean dumpAll) {
13448        String innerPrefix = prefix + "  ";
13449        synchronized (this) {
13450            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13451                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13452                    pw.print(" pid=");
13453                    if (r.app != null) pw.println(r.app.pid);
13454                    else pw.println("(not running)");
13455            if (dumpAll) {
13456                r.dump(pw, innerPrefix);
13457            }
13458        }
13459        if (r.app != null && r.app.thread != null) {
13460            // flush anything that is already in the PrintWriter since the thread is going
13461            // to write to the file descriptor directly
13462            pw.flush();
13463            try {
13464                TransferPipe tp = new TransferPipe();
13465                try {
13466                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13467                            r.appToken, innerPrefix, args);
13468                    tp.go(fd);
13469                } finally {
13470                    tp.kill();
13471                }
13472            } catch (IOException e) {
13473                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13474            } catch (RemoteException e) {
13475                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13476            }
13477        }
13478    }
13479
13480    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13481            int opti, boolean dumpAll, String dumpPackage) {
13482        boolean needSep = false;
13483        boolean onlyHistory = false;
13484        boolean printedAnything = false;
13485
13486        if ("history".equals(dumpPackage)) {
13487            if (opti < args.length && "-s".equals(args[opti])) {
13488                dumpAll = false;
13489            }
13490            onlyHistory = true;
13491            dumpPackage = null;
13492        }
13493
13494        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13495        if (!onlyHistory && dumpAll) {
13496            if (mRegisteredReceivers.size() > 0) {
13497                boolean printed = false;
13498                Iterator it = mRegisteredReceivers.values().iterator();
13499                while (it.hasNext()) {
13500                    ReceiverList r = (ReceiverList)it.next();
13501                    if (dumpPackage != null && (r.app == null ||
13502                            !dumpPackage.equals(r.app.info.packageName))) {
13503                        continue;
13504                    }
13505                    if (!printed) {
13506                        pw.println("  Registered Receivers:");
13507                        needSep = true;
13508                        printed = true;
13509                        printedAnything = true;
13510                    }
13511                    pw.print("  * "); pw.println(r);
13512                    r.dump(pw, "    ");
13513                }
13514            }
13515
13516            if (mReceiverResolver.dump(pw, needSep ?
13517                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13518                    "    ", dumpPackage, false, false)) {
13519                needSep = true;
13520                printedAnything = true;
13521            }
13522        }
13523
13524        for (BroadcastQueue q : mBroadcastQueues) {
13525            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13526            printedAnything |= needSep;
13527        }
13528
13529        needSep = true;
13530
13531        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13532            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13533                if (needSep) {
13534                    pw.println();
13535                }
13536                needSep = true;
13537                printedAnything = true;
13538                pw.print("  Sticky broadcasts for user ");
13539                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13540                StringBuilder sb = new StringBuilder(128);
13541                for (Map.Entry<String, ArrayList<Intent>> ent
13542                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13543                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13544                    if (dumpAll) {
13545                        pw.println(":");
13546                        ArrayList<Intent> intents = ent.getValue();
13547                        final int N = intents.size();
13548                        for (int i=0; i<N; i++) {
13549                            sb.setLength(0);
13550                            sb.append("    Intent: ");
13551                            intents.get(i).toShortString(sb, false, true, false, false);
13552                            pw.println(sb.toString());
13553                            Bundle bundle = intents.get(i).getExtras();
13554                            if (bundle != null) {
13555                                pw.print("      ");
13556                                pw.println(bundle.toString());
13557                            }
13558                        }
13559                    } else {
13560                        pw.println("");
13561                    }
13562                }
13563            }
13564        }
13565
13566        if (!onlyHistory && dumpAll) {
13567            pw.println();
13568            for (BroadcastQueue queue : mBroadcastQueues) {
13569                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13570                        + queue.mBroadcastsScheduled);
13571            }
13572            pw.println("  mHandler:");
13573            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13574            needSep = true;
13575            printedAnything = true;
13576        }
13577
13578        if (!printedAnything) {
13579            pw.println("  (nothing)");
13580        }
13581    }
13582
13583    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13584            int opti, boolean dumpAll, String dumpPackage) {
13585        boolean needSep;
13586        boolean printedAnything = false;
13587
13588        ItemMatcher matcher = new ItemMatcher();
13589        matcher.build(args, opti);
13590
13591        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13592
13593        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13594        printedAnything |= needSep;
13595
13596        if (mLaunchingProviders.size() > 0) {
13597            boolean printed = false;
13598            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13599                ContentProviderRecord r = mLaunchingProviders.get(i);
13600                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13601                    continue;
13602                }
13603                if (!printed) {
13604                    if (needSep) pw.println();
13605                    needSep = true;
13606                    pw.println("  Launching content providers:");
13607                    printed = true;
13608                    printedAnything = true;
13609                }
13610                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13611                        pw.println(r);
13612            }
13613        }
13614
13615        if (mGrantedUriPermissions.size() > 0) {
13616            boolean printed = false;
13617            int dumpUid = -2;
13618            if (dumpPackage != null) {
13619                try {
13620                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13621                } catch (NameNotFoundException e) {
13622                    dumpUid = -1;
13623                }
13624            }
13625            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13626                int uid = mGrantedUriPermissions.keyAt(i);
13627                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13628                    continue;
13629                }
13630                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13631                if (!printed) {
13632                    if (needSep) pw.println();
13633                    needSep = true;
13634                    pw.println("  Granted Uri Permissions:");
13635                    printed = true;
13636                    printedAnything = true;
13637                }
13638                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13639                for (UriPermission perm : perms.values()) {
13640                    pw.print("    "); pw.println(perm);
13641                    if (dumpAll) {
13642                        perm.dump(pw, "      ");
13643                    }
13644                }
13645            }
13646        }
13647
13648        if (!printedAnything) {
13649            pw.println("  (nothing)");
13650        }
13651    }
13652
13653    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13654            int opti, boolean dumpAll, String dumpPackage) {
13655        boolean printed = false;
13656
13657        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13658
13659        if (mIntentSenderRecords.size() > 0) {
13660            Iterator<WeakReference<PendingIntentRecord>> it
13661                    = mIntentSenderRecords.values().iterator();
13662            while (it.hasNext()) {
13663                WeakReference<PendingIntentRecord> ref = it.next();
13664                PendingIntentRecord rec = ref != null ? ref.get(): null;
13665                if (dumpPackage != null && (rec == null
13666                        || !dumpPackage.equals(rec.key.packageName))) {
13667                    continue;
13668                }
13669                printed = true;
13670                if (rec != null) {
13671                    pw.print("  * "); pw.println(rec);
13672                    if (dumpAll) {
13673                        rec.dump(pw, "    ");
13674                    }
13675                } else {
13676                    pw.print("  * "); pw.println(ref);
13677                }
13678            }
13679        }
13680
13681        if (!printed) {
13682            pw.println("  (nothing)");
13683        }
13684    }
13685
13686    private static final int dumpProcessList(PrintWriter pw,
13687            ActivityManagerService service, List list,
13688            String prefix, String normalLabel, String persistentLabel,
13689            String dumpPackage) {
13690        int numPers = 0;
13691        final int N = list.size()-1;
13692        for (int i=N; i>=0; i--) {
13693            ProcessRecord r = (ProcessRecord)list.get(i);
13694            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13695                continue;
13696            }
13697            pw.println(String.format("%s%s #%2d: %s",
13698                    prefix, (r.persistent ? persistentLabel : normalLabel),
13699                    i, r.toString()));
13700            if (r.persistent) {
13701                numPers++;
13702            }
13703        }
13704        return numPers;
13705    }
13706
13707    private static final boolean dumpProcessOomList(PrintWriter pw,
13708            ActivityManagerService service, List<ProcessRecord> origList,
13709            String prefix, String normalLabel, String persistentLabel,
13710            boolean inclDetails, String dumpPackage) {
13711
13712        ArrayList<Pair<ProcessRecord, Integer>> list
13713                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13714        for (int i=0; i<origList.size(); i++) {
13715            ProcessRecord r = origList.get(i);
13716            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13717                continue;
13718            }
13719            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13720        }
13721
13722        if (list.size() <= 0) {
13723            return false;
13724        }
13725
13726        Comparator<Pair<ProcessRecord, Integer>> comparator
13727                = new Comparator<Pair<ProcessRecord, Integer>>() {
13728            @Override
13729            public int compare(Pair<ProcessRecord, Integer> object1,
13730                    Pair<ProcessRecord, Integer> object2) {
13731                if (object1.first.setAdj != object2.first.setAdj) {
13732                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13733                }
13734                if (object1.second.intValue() != object2.second.intValue()) {
13735                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13736                }
13737                return 0;
13738            }
13739        };
13740
13741        Collections.sort(list, comparator);
13742
13743        final long curRealtime = SystemClock.elapsedRealtime();
13744        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13745        final long curUptime = SystemClock.uptimeMillis();
13746        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13747
13748        for (int i=list.size()-1; i>=0; i--) {
13749            ProcessRecord r = list.get(i).first;
13750            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13751            char schedGroup;
13752            switch (r.setSchedGroup) {
13753                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13754                    schedGroup = 'B';
13755                    break;
13756                case Process.THREAD_GROUP_DEFAULT:
13757                    schedGroup = 'F';
13758                    break;
13759                default:
13760                    schedGroup = '?';
13761                    break;
13762            }
13763            char foreground;
13764            if (r.foregroundActivities) {
13765                foreground = 'A';
13766            } else if (r.foregroundServices) {
13767                foreground = 'S';
13768            } else {
13769                foreground = ' ';
13770            }
13771            String procState = ProcessList.makeProcStateString(r.curProcState);
13772            pw.print(prefix);
13773            pw.print(r.persistent ? persistentLabel : normalLabel);
13774            pw.print(" #");
13775            int num = (origList.size()-1)-list.get(i).second;
13776            if (num < 10) pw.print(' ');
13777            pw.print(num);
13778            pw.print(": ");
13779            pw.print(oomAdj);
13780            pw.print(' ');
13781            pw.print(schedGroup);
13782            pw.print('/');
13783            pw.print(foreground);
13784            pw.print('/');
13785            pw.print(procState);
13786            pw.print(" trm:");
13787            if (r.trimMemoryLevel < 10) pw.print(' ');
13788            pw.print(r.trimMemoryLevel);
13789            pw.print(' ');
13790            pw.print(r.toShortString());
13791            pw.print(" (");
13792            pw.print(r.adjType);
13793            pw.println(')');
13794            if (r.adjSource != null || r.adjTarget != null) {
13795                pw.print(prefix);
13796                pw.print("    ");
13797                if (r.adjTarget instanceof ComponentName) {
13798                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13799                } else if (r.adjTarget != null) {
13800                    pw.print(r.adjTarget.toString());
13801                } else {
13802                    pw.print("{null}");
13803                }
13804                pw.print("<=");
13805                if (r.adjSource instanceof ProcessRecord) {
13806                    pw.print("Proc{");
13807                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13808                    pw.println("}");
13809                } else if (r.adjSource != null) {
13810                    pw.println(r.adjSource.toString());
13811                } else {
13812                    pw.println("{null}");
13813                }
13814            }
13815            if (inclDetails) {
13816                pw.print(prefix);
13817                pw.print("    ");
13818                pw.print("oom: max="); pw.print(r.maxAdj);
13819                pw.print(" curRaw="); pw.print(r.curRawAdj);
13820                pw.print(" setRaw="); pw.print(r.setRawAdj);
13821                pw.print(" cur="); pw.print(r.curAdj);
13822                pw.print(" set="); pw.println(r.setAdj);
13823                pw.print(prefix);
13824                pw.print("    ");
13825                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13826                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13827                pw.print(" lastPss="); pw.print(r.lastPss);
13828                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13829                pw.print(prefix);
13830                pw.print("    ");
13831                pw.print("cached="); pw.print(r.cached);
13832                pw.print(" empty="); pw.print(r.empty);
13833                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13834
13835                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13836                    if (r.lastWakeTime != 0) {
13837                        long wtime;
13838                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13839                        synchronized (stats) {
13840                            wtime = stats.getProcessWakeTime(r.info.uid,
13841                                    r.pid, curRealtime);
13842                        }
13843                        long timeUsed = wtime - r.lastWakeTime;
13844                        pw.print(prefix);
13845                        pw.print("    ");
13846                        pw.print("keep awake over ");
13847                        TimeUtils.formatDuration(realtimeSince, pw);
13848                        pw.print(" used ");
13849                        TimeUtils.formatDuration(timeUsed, pw);
13850                        pw.print(" (");
13851                        pw.print((timeUsed*100)/realtimeSince);
13852                        pw.println("%)");
13853                    }
13854                    if (r.lastCpuTime != 0) {
13855                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13856                        pw.print(prefix);
13857                        pw.print("    ");
13858                        pw.print("run cpu over ");
13859                        TimeUtils.formatDuration(uptimeSince, pw);
13860                        pw.print(" used ");
13861                        TimeUtils.formatDuration(timeUsed, pw);
13862                        pw.print(" (");
13863                        pw.print((timeUsed*100)/uptimeSince);
13864                        pw.println("%)");
13865                    }
13866                }
13867            }
13868        }
13869        return true;
13870    }
13871
13872    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13873            String[] args) {
13874        ArrayList<ProcessRecord> procs;
13875        synchronized (this) {
13876            if (args != null && args.length > start
13877                    && args[start].charAt(0) != '-') {
13878                procs = new ArrayList<ProcessRecord>();
13879                int pid = -1;
13880                try {
13881                    pid = Integer.parseInt(args[start]);
13882                } catch (NumberFormatException e) {
13883                }
13884                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13885                    ProcessRecord proc = mLruProcesses.get(i);
13886                    if (proc.pid == pid) {
13887                        procs.add(proc);
13888                    } else if (allPkgs && proc.pkgList != null
13889                            && proc.pkgList.containsKey(args[start])) {
13890                        procs.add(proc);
13891                    } else if (proc.processName.equals(args[start])) {
13892                        procs.add(proc);
13893                    }
13894                }
13895                if (procs.size() <= 0) {
13896                    return null;
13897                }
13898            } else {
13899                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13900            }
13901        }
13902        return procs;
13903    }
13904
13905    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13906            PrintWriter pw, String[] args) {
13907        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13908        if (procs == null) {
13909            pw.println("No process found for: " + args[0]);
13910            return;
13911        }
13912
13913        long uptime = SystemClock.uptimeMillis();
13914        long realtime = SystemClock.elapsedRealtime();
13915        pw.println("Applications Graphics Acceleration Info:");
13916        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13917
13918        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13919            ProcessRecord r = procs.get(i);
13920            if (r.thread != null) {
13921                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13922                pw.flush();
13923                try {
13924                    TransferPipe tp = new TransferPipe();
13925                    try {
13926                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13927                        tp.go(fd);
13928                    } finally {
13929                        tp.kill();
13930                    }
13931                } catch (IOException e) {
13932                    pw.println("Failure while dumping the app: " + r);
13933                    pw.flush();
13934                } catch (RemoteException e) {
13935                    pw.println("Got a RemoteException while dumping the app " + r);
13936                    pw.flush();
13937                }
13938            }
13939        }
13940    }
13941
13942    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13943        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13944        if (procs == null) {
13945            pw.println("No process found for: " + args[0]);
13946            return;
13947        }
13948
13949        pw.println("Applications Database Info:");
13950
13951        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13952            ProcessRecord r = procs.get(i);
13953            if (r.thread != null) {
13954                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13955                pw.flush();
13956                try {
13957                    TransferPipe tp = new TransferPipe();
13958                    try {
13959                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13960                        tp.go(fd);
13961                    } finally {
13962                        tp.kill();
13963                    }
13964                } catch (IOException e) {
13965                    pw.println("Failure while dumping the app: " + r);
13966                    pw.flush();
13967                } catch (RemoteException e) {
13968                    pw.println("Got a RemoteException while dumping the app " + r);
13969                    pw.flush();
13970                }
13971            }
13972        }
13973    }
13974
13975    final static class MemItem {
13976        final boolean isProc;
13977        final String label;
13978        final String shortLabel;
13979        final long pss;
13980        final int id;
13981        final boolean hasActivities;
13982        ArrayList<MemItem> subitems;
13983
13984        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13985                boolean _hasActivities) {
13986            isProc = true;
13987            label = _label;
13988            shortLabel = _shortLabel;
13989            pss = _pss;
13990            id = _id;
13991            hasActivities = _hasActivities;
13992        }
13993
13994        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13995            isProc = false;
13996            label = _label;
13997            shortLabel = _shortLabel;
13998            pss = _pss;
13999            id = _id;
14000            hasActivities = false;
14001        }
14002    }
14003
14004    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14005            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14006        if (sort && !isCompact) {
14007            Collections.sort(items, new Comparator<MemItem>() {
14008                @Override
14009                public int compare(MemItem lhs, MemItem rhs) {
14010                    if (lhs.pss < rhs.pss) {
14011                        return 1;
14012                    } else if (lhs.pss > rhs.pss) {
14013                        return -1;
14014                    }
14015                    return 0;
14016                }
14017            });
14018        }
14019
14020        for (int i=0; i<items.size(); i++) {
14021            MemItem mi = items.get(i);
14022            if (!isCompact) {
14023                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14024            } else if (mi.isProc) {
14025                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14026                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14027                pw.println(mi.hasActivities ? ",a" : ",e");
14028            } else {
14029                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14030                pw.println(mi.pss);
14031            }
14032            if (mi.subitems != null) {
14033                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14034                        true, isCompact);
14035            }
14036        }
14037    }
14038
14039    // These are in KB.
14040    static final long[] DUMP_MEM_BUCKETS = new long[] {
14041        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14042        120*1024, 160*1024, 200*1024,
14043        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14044        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14045    };
14046
14047    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14048            boolean stackLike) {
14049        int start = label.lastIndexOf('.');
14050        if (start >= 0) start++;
14051        else start = 0;
14052        int end = label.length();
14053        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14054            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14055                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14056                out.append(bucket);
14057                out.append(stackLike ? "MB." : "MB ");
14058                out.append(label, start, end);
14059                return;
14060            }
14061        }
14062        out.append(memKB/1024);
14063        out.append(stackLike ? "MB." : "MB ");
14064        out.append(label, start, end);
14065    }
14066
14067    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14068            ProcessList.NATIVE_ADJ,
14069            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14070            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14071            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14072            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14073            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14074            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14075    };
14076    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14077            "Native",
14078            "System", "Persistent", "Persistent Service", "Foreground",
14079            "Visible", "Perceptible",
14080            "Heavy Weight", "Backup",
14081            "A Services", "Home",
14082            "Previous", "B Services", "Cached"
14083    };
14084    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14085            "native",
14086            "sys", "pers", "persvc", "fore",
14087            "vis", "percept",
14088            "heavy", "backup",
14089            "servicea", "home",
14090            "prev", "serviceb", "cached"
14091    };
14092
14093    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14094            long realtime, boolean isCheckinRequest, boolean isCompact) {
14095        if (isCheckinRequest || isCompact) {
14096            // short checkin version
14097            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14098        } else {
14099            pw.println("Applications Memory Usage (kB):");
14100            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14101        }
14102    }
14103
14104    private static final int KSM_SHARED = 0;
14105    private static final int KSM_SHARING = 1;
14106    private static final int KSM_UNSHARED = 2;
14107    private static final int KSM_VOLATILE = 3;
14108
14109    private final long[] getKsmInfo() {
14110        long[] longOut = new long[4];
14111        final int[] SINGLE_LONG_FORMAT = new int[] {
14112            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14113        };
14114        long[] longTmp = new long[1];
14115        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14116                SINGLE_LONG_FORMAT, null, longTmp, null);
14117        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14118        longTmp[0] = 0;
14119        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14120                SINGLE_LONG_FORMAT, null, longTmp, null);
14121        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14122        longTmp[0] = 0;
14123        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14124                SINGLE_LONG_FORMAT, null, longTmp, null);
14125        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14126        longTmp[0] = 0;
14127        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14128                SINGLE_LONG_FORMAT, null, longTmp, null);
14129        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14130        return longOut;
14131    }
14132
14133    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14134            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14135        boolean dumpDetails = false;
14136        boolean dumpFullDetails = false;
14137        boolean dumpDalvik = false;
14138        boolean oomOnly = false;
14139        boolean isCompact = false;
14140        boolean localOnly = false;
14141        boolean packages = false;
14142
14143        int opti = 0;
14144        while (opti < args.length) {
14145            String opt = args[opti];
14146            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14147                break;
14148            }
14149            opti++;
14150            if ("-a".equals(opt)) {
14151                dumpDetails = true;
14152                dumpFullDetails = true;
14153                dumpDalvik = true;
14154            } else if ("-d".equals(opt)) {
14155                dumpDalvik = true;
14156            } else if ("-c".equals(opt)) {
14157                isCompact = true;
14158            } else if ("--oom".equals(opt)) {
14159                oomOnly = true;
14160            } else if ("--local".equals(opt)) {
14161                localOnly = true;
14162            } else if ("--package".equals(opt)) {
14163                packages = true;
14164            } else if ("-h".equals(opt)) {
14165                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14166                pw.println("  -a: include all available information for each process.");
14167                pw.println("  -d: include dalvik details when dumping process details.");
14168                pw.println("  -c: dump in a compact machine-parseable representation.");
14169                pw.println("  --oom: only show processes organized by oom adj.");
14170                pw.println("  --local: only collect details locally, don't call process.");
14171                pw.println("  --package: interpret process arg as package, dumping all");
14172                pw.println("             processes that have loaded that package.");
14173                pw.println("If [process] is specified it can be the name or ");
14174                pw.println("pid of a specific process to dump.");
14175                return;
14176            } else {
14177                pw.println("Unknown argument: " + opt + "; use -h for help");
14178            }
14179        }
14180
14181        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14182        long uptime = SystemClock.uptimeMillis();
14183        long realtime = SystemClock.elapsedRealtime();
14184        final long[] tmpLong = new long[1];
14185
14186        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14187        if (procs == null) {
14188            // No Java processes.  Maybe they want to print a native process.
14189            if (args != null && args.length > opti
14190                    && args[opti].charAt(0) != '-') {
14191                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14192                        = new ArrayList<ProcessCpuTracker.Stats>();
14193                updateCpuStatsNow();
14194                int findPid = -1;
14195                try {
14196                    findPid = Integer.parseInt(args[opti]);
14197                } catch (NumberFormatException e) {
14198                }
14199                synchronized (mProcessCpuTracker) {
14200                    final int N = mProcessCpuTracker.countStats();
14201                    for (int i=0; i<N; i++) {
14202                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14203                        if (st.pid == findPid || (st.baseName != null
14204                                && st.baseName.equals(args[opti]))) {
14205                            nativeProcs.add(st);
14206                        }
14207                    }
14208                }
14209                if (nativeProcs.size() > 0) {
14210                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14211                            isCompact);
14212                    Debug.MemoryInfo mi = null;
14213                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14214                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14215                        final int pid = r.pid;
14216                        if (!isCheckinRequest && dumpDetails) {
14217                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14218                        }
14219                        if (mi == null) {
14220                            mi = new Debug.MemoryInfo();
14221                        }
14222                        if (dumpDetails || (!brief && !oomOnly)) {
14223                            Debug.getMemoryInfo(pid, mi);
14224                        } else {
14225                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14226                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14227                        }
14228                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14229                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14230                        if (isCheckinRequest) {
14231                            pw.println();
14232                        }
14233                    }
14234                    return;
14235                }
14236            }
14237            pw.println("No process found for: " + args[opti]);
14238            return;
14239        }
14240
14241        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14242            dumpDetails = true;
14243        }
14244
14245        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14246
14247        String[] innerArgs = new String[args.length-opti];
14248        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14249
14250        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14251        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14252        long nativePss = 0;
14253        long dalvikPss = 0;
14254        long otherPss = 0;
14255        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14256
14257        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14258        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14259                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14260
14261        long totalPss = 0;
14262        long cachedPss = 0;
14263
14264        Debug.MemoryInfo mi = null;
14265        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14266            final ProcessRecord r = procs.get(i);
14267            final IApplicationThread thread;
14268            final int pid;
14269            final int oomAdj;
14270            final boolean hasActivities;
14271            synchronized (this) {
14272                thread = r.thread;
14273                pid = r.pid;
14274                oomAdj = r.getSetAdjWithServices();
14275                hasActivities = r.activities.size() > 0;
14276            }
14277            if (thread != null) {
14278                if (!isCheckinRequest && dumpDetails) {
14279                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14280                }
14281                if (mi == null) {
14282                    mi = new Debug.MemoryInfo();
14283                }
14284                if (dumpDetails || (!brief && !oomOnly)) {
14285                    Debug.getMemoryInfo(pid, mi);
14286                } else {
14287                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14288                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14289                }
14290                if (dumpDetails) {
14291                    if (localOnly) {
14292                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14293                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14294                        if (isCheckinRequest) {
14295                            pw.println();
14296                        }
14297                    } else {
14298                        try {
14299                            pw.flush();
14300                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14301                                    dumpDalvik, innerArgs);
14302                        } catch (RemoteException e) {
14303                            if (!isCheckinRequest) {
14304                                pw.println("Got RemoteException!");
14305                                pw.flush();
14306                            }
14307                        }
14308                    }
14309                }
14310
14311                final long myTotalPss = mi.getTotalPss();
14312                final long myTotalUss = mi.getTotalUss();
14313
14314                synchronized (this) {
14315                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14316                        // Record this for posterity if the process has been stable.
14317                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14318                    }
14319                }
14320
14321                if (!isCheckinRequest && mi != null) {
14322                    totalPss += myTotalPss;
14323                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14324                            (hasActivities ? " / activities)" : ")"),
14325                            r.processName, myTotalPss, pid, hasActivities);
14326                    procMems.add(pssItem);
14327                    procMemsMap.put(pid, pssItem);
14328
14329                    nativePss += mi.nativePss;
14330                    dalvikPss += mi.dalvikPss;
14331                    otherPss += mi.otherPss;
14332                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14333                        long mem = mi.getOtherPss(j);
14334                        miscPss[j] += mem;
14335                        otherPss -= mem;
14336                    }
14337
14338                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14339                        cachedPss += myTotalPss;
14340                    }
14341
14342                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14343                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14344                                || oomIndex == (oomPss.length-1)) {
14345                            oomPss[oomIndex] += myTotalPss;
14346                            if (oomProcs[oomIndex] == null) {
14347                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14348                            }
14349                            oomProcs[oomIndex].add(pssItem);
14350                            break;
14351                        }
14352                    }
14353                }
14354            }
14355        }
14356
14357        long nativeProcTotalPss = 0;
14358
14359        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14360            // If we are showing aggregations, also look for native processes to
14361            // include so that our aggregations are more accurate.
14362            updateCpuStatsNow();
14363            mi = null;
14364            synchronized (mProcessCpuTracker) {
14365                final int N = mProcessCpuTracker.countStats();
14366                for (int i=0; i<N; i++) {
14367                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14368                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14369                        if (mi == null) {
14370                            mi = new Debug.MemoryInfo();
14371                        }
14372                        if (!brief && !oomOnly) {
14373                            Debug.getMemoryInfo(st.pid, mi);
14374                        } else {
14375                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14376                            mi.nativePrivateDirty = (int)tmpLong[0];
14377                        }
14378
14379                        final long myTotalPss = mi.getTotalPss();
14380                        totalPss += myTotalPss;
14381                        nativeProcTotalPss += myTotalPss;
14382
14383                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14384                                st.name, myTotalPss, st.pid, false);
14385                        procMems.add(pssItem);
14386
14387                        nativePss += mi.nativePss;
14388                        dalvikPss += mi.dalvikPss;
14389                        otherPss += mi.otherPss;
14390                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14391                            long mem = mi.getOtherPss(j);
14392                            miscPss[j] += mem;
14393                            otherPss -= mem;
14394                        }
14395                        oomPss[0] += myTotalPss;
14396                        if (oomProcs[0] == null) {
14397                            oomProcs[0] = new ArrayList<MemItem>();
14398                        }
14399                        oomProcs[0].add(pssItem);
14400                    }
14401                }
14402            }
14403
14404            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14405
14406            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14407            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14408            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14409            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14410                String label = Debug.MemoryInfo.getOtherLabel(j);
14411                catMems.add(new MemItem(label, label, miscPss[j], j));
14412            }
14413
14414            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14415            for (int j=0; j<oomPss.length; j++) {
14416                if (oomPss[j] != 0) {
14417                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14418                            : DUMP_MEM_OOM_LABEL[j];
14419                    MemItem item = new MemItem(label, label, oomPss[j],
14420                            DUMP_MEM_OOM_ADJ[j]);
14421                    item.subitems = oomProcs[j];
14422                    oomMems.add(item);
14423                }
14424            }
14425
14426            if (!brief && !oomOnly && !isCompact) {
14427                pw.println();
14428                pw.println("Total PSS by process:");
14429                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14430                pw.println();
14431            }
14432            if (!isCompact) {
14433                pw.println("Total PSS by OOM adjustment:");
14434            }
14435            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14436            if (!brief && !oomOnly) {
14437                PrintWriter out = categoryPw != null ? categoryPw : pw;
14438                if (!isCompact) {
14439                    out.println();
14440                    out.println("Total PSS by category:");
14441                }
14442                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14443            }
14444            if (!isCompact) {
14445                pw.println();
14446            }
14447            MemInfoReader memInfo = new MemInfoReader();
14448            memInfo.readMemInfo();
14449            if (nativeProcTotalPss > 0) {
14450                synchronized (this) {
14451                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14452                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14453                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14454                }
14455            }
14456            if (!brief) {
14457                if (!isCompact) {
14458                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14459                    pw.print(" kB (status ");
14460                    switch (mLastMemoryLevel) {
14461                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14462                            pw.println("normal)");
14463                            break;
14464                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14465                            pw.println("moderate)");
14466                            break;
14467                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14468                            pw.println("low)");
14469                            break;
14470                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14471                            pw.println("critical)");
14472                            break;
14473                        default:
14474                            pw.print(mLastMemoryLevel);
14475                            pw.println(")");
14476                            break;
14477                    }
14478                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14479                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14480                            pw.print(cachedPss); pw.print(" cached pss + ");
14481                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14482                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14483                } else {
14484                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14485                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14486                            + memInfo.getFreeSizeKb()); pw.print(",");
14487                    pw.println(totalPss - cachedPss);
14488                }
14489            }
14490            if (!isCompact) {
14491                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14492                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14493                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14494                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14495                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14496                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14497                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14498            }
14499            if (!brief) {
14500                if (memInfo.getZramTotalSizeKb() != 0) {
14501                    if (!isCompact) {
14502                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14503                                pw.print(" kB physical used for ");
14504                                pw.print(memInfo.getSwapTotalSizeKb()
14505                                        - memInfo.getSwapFreeSizeKb());
14506                                pw.print(" kB in swap (");
14507                                pw.print(memInfo.getSwapTotalSizeKb());
14508                                pw.println(" kB total swap)");
14509                    } else {
14510                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14511                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14512                                pw.println(memInfo.getSwapFreeSizeKb());
14513                    }
14514                }
14515                final long[] ksm = getKsmInfo();
14516                if (!isCompact) {
14517                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14518                            || ksm[KSM_VOLATILE] != 0) {
14519                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14520                                pw.print(" kB saved from shared ");
14521                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14522                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14523                                pw.print(" kB unshared; ");
14524                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14525                    }
14526                    pw.print("   Tuning: ");
14527                    pw.print(ActivityManager.staticGetMemoryClass());
14528                    pw.print(" (large ");
14529                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14530                    pw.print("), oom ");
14531                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14532                    pw.print(" kB");
14533                    pw.print(", restore limit ");
14534                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14535                    pw.print(" kB");
14536                    if (ActivityManager.isLowRamDeviceStatic()) {
14537                        pw.print(" (low-ram)");
14538                    }
14539                    if (ActivityManager.isHighEndGfx()) {
14540                        pw.print(" (high-end-gfx)");
14541                    }
14542                    pw.println();
14543                } else {
14544                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14545                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14546                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14547                    pw.print("tuning,");
14548                    pw.print(ActivityManager.staticGetMemoryClass());
14549                    pw.print(',');
14550                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14551                    pw.print(',');
14552                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14553                    if (ActivityManager.isLowRamDeviceStatic()) {
14554                        pw.print(",low-ram");
14555                    }
14556                    if (ActivityManager.isHighEndGfx()) {
14557                        pw.print(",high-end-gfx");
14558                    }
14559                    pw.println();
14560                }
14561            }
14562        }
14563    }
14564
14565    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14566            long memtrack, String name) {
14567        sb.append("  ");
14568        sb.append(ProcessList.makeOomAdjString(oomAdj));
14569        sb.append(' ');
14570        sb.append(ProcessList.makeProcStateString(procState));
14571        sb.append(' ');
14572        ProcessList.appendRamKb(sb, pss);
14573        sb.append(" kB: ");
14574        sb.append(name);
14575        if (memtrack > 0) {
14576            sb.append(" (");
14577            sb.append(memtrack);
14578            sb.append(" kB memtrack)");
14579        }
14580    }
14581
14582    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14583        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14584        sb.append(" (pid ");
14585        sb.append(mi.pid);
14586        sb.append(") ");
14587        sb.append(mi.adjType);
14588        sb.append('\n');
14589        if (mi.adjReason != null) {
14590            sb.append("                      ");
14591            sb.append(mi.adjReason);
14592            sb.append('\n');
14593        }
14594    }
14595
14596    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14597        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14598        for (int i=0, N=memInfos.size(); i<N; i++) {
14599            ProcessMemInfo mi = memInfos.get(i);
14600            infoMap.put(mi.pid, mi);
14601        }
14602        updateCpuStatsNow();
14603        long[] memtrackTmp = new long[1];
14604        synchronized (mProcessCpuTracker) {
14605            final int N = mProcessCpuTracker.countStats();
14606            for (int i=0; i<N; i++) {
14607                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14608                if (st.vsize > 0) {
14609                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14610                    if (pss > 0) {
14611                        if (infoMap.indexOfKey(st.pid) < 0) {
14612                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14613                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14614                            mi.pss = pss;
14615                            mi.memtrack = memtrackTmp[0];
14616                            memInfos.add(mi);
14617                        }
14618                    }
14619                }
14620            }
14621        }
14622
14623        long totalPss = 0;
14624        long totalMemtrack = 0;
14625        for (int i=0, N=memInfos.size(); i<N; i++) {
14626            ProcessMemInfo mi = memInfos.get(i);
14627            if (mi.pss == 0) {
14628                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14629                mi.memtrack = memtrackTmp[0];
14630            }
14631            totalPss += mi.pss;
14632            totalMemtrack += mi.memtrack;
14633        }
14634        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14635            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14636                if (lhs.oomAdj != rhs.oomAdj) {
14637                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14638                }
14639                if (lhs.pss != rhs.pss) {
14640                    return lhs.pss < rhs.pss ? 1 : -1;
14641                }
14642                return 0;
14643            }
14644        });
14645
14646        StringBuilder tag = new StringBuilder(128);
14647        StringBuilder stack = new StringBuilder(128);
14648        tag.append("Low on memory -- ");
14649        appendMemBucket(tag, totalPss, "total", false);
14650        appendMemBucket(stack, totalPss, "total", true);
14651
14652        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14653        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14654        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14655
14656        boolean firstLine = true;
14657        int lastOomAdj = Integer.MIN_VALUE;
14658        long extraNativeRam = 0;
14659        long extraNativeMemtrack = 0;
14660        long cachedPss = 0;
14661        for (int i=0, N=memInfos.size(); i<N; i++) {
14662            ProcessMemInfo mi = memInfos.get(i);
14663
14664            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14665                cachedPss += mi.pss;
14666            }
14667
14668            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14669                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14670                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14671                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14672                if (lastOomAdj != mi.oomAdj) {
14673                    lastOomAdj = mi.oomAdj;
14674                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14675                        tag.append(" / ");
14676                    }
14677                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14678                        if (firstLine) {
14679                            stack.append(":");
14680                            firstLine = false;
14681                        }
14682                        stack.append("\n\t at ");
14683                    } else {
14684                        stack.append("$");
14685                    }
14686                } else {
14687                    tag.append(" ");
14688                    stack.append("$");
14689                }
14690                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14691                    appendMemBucket(tag, mi.pss, mi.name, false);
14692                }
14693                appendMemBucket(stack, mi.pss, mi.name, true);
14694                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14695                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14696                    stack.append("(");
14697                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14698                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14699                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14700                            stack.append(":");
14701                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14702                        }
14703                    }
14704                    stack.append(")");
14705                }
14706            }
14707
14708            appendMemInfo(fullNativeBuilder, mi);
14709            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14710                // The short form only has native processes that are >= 512K.
14711                if (mi.pss >= 512) {
14712                    appendMemInfo(shortNativeBuilder, mi);
14713                } else {
14714                    extraNativeRam += mi.pss;
14715                    extraNativeMemtrack += mi.memtrack;
14716                }
14717            } else {
14718                // Short form has all other details, but if we have collected RAM
14719                // from smaller native processes let's dump a summary of that.
14720                if (extraNativeRam > 0) {
14721                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14722                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14723                    shortNativeBuilder.append('\n');
14724                    extraNativeRam = 0;
14725                }
14726                appendMemInfo(fullJavaBuilder, mi);
14727            }
14728        }
14729
14730        fullJavaBuilder.append("           ");
14731        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14732        fullJavaBuilder.append(" kB: TOTAL");
14733        if (totalMemtrack > 0) {
14734            fullJavaBuilder.append(" (");
14735            fullJavaBuilder.append(totalMemtrack);
14736            fullJavaBuilder.append(" kB memtrack)");
14737        } else {
14738        }
14739        fullJavaBuilder.append("\n");
14740
14741        MemInfoReader memInfo = new MemInfoReader();
14742        memInfo.readMemInfo();
14743        final long[] infos = memInfo.getRawInfo();
14744
14745        StringBuilder memInfoBuilder = new StringBuilder(1024);
14746        Debug.getMemInfo(infos);
14747        memInfoBuilder.append("  MemInfo: ");
14748        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14749        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14750        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14751        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14752        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14753        memInfoBuilder.append("           ");
14754        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14755        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14756        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14757        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14758        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14759            memInfoBuilder.append("  ZRAM: ");
14760            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14761            memInfoBuilder.append(" kB RAM, ");
14762            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14763            memInfoBuilder.append(" kB swap total, ");
14764            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14765            memInfoBuilder.append(" kB swap free\n");
14766        }
14767        final long[] ksm = getKsmInfo();
14768        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14769                || ksm[KSM_VOLATILE] != 0) {
14770            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14771            memInfoBuilder.append(" kB saved from shared ");
14772            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14773            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14774            memInfoBuilder.append(" kB unshared; ");
14775            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14776        }
14777        memInfoBuilder.append("  Free RAM: ");
14778        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14779                + memInfo.getFreeSizeKb());
14780        memInfoBuilder.append(" kB\n");
14781        memInfoBuilder.append("  Used RAM: ");
14782        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14783        memInfoBuilder.append(" kB\n");
14784        memInfoBuilder.append("  Lost RAM: ");
14785        memInfoBuilder.append(memInfo.getTotalSizeKb()
14786                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14787                - memInfo.getKernelUsedSizeKb());
14788        memInfoBuilder.append(" kB\n");
14789        Slog.i(TAG, "Low on memory:");
14790        Slog.i(TAG, shortNativeBuilder.toString());
14791        Slog.i(TAG, fullJavaBuilder.toString());
14792        Slog.i(TAG, memInfoBuilder.toString());
14793
14794        StringBuilder dropBuilder = new StringBuilder(1024);
14795        /*
14796        StringWriter oomSw = new StringWriter();
14797        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14798        StringWriter catSw = new StringWriter();
14799        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14800        String[] emptyArgs = new String[] { };
14801        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14802        oomPw.flush();
14803        String oomString = oomSw.toString();
14804        */
14805        dropBuilder.append("Low on memory:");
14806        dropBuilder.append(stack);
14807        dropBuilder.append('\n');
14808        dropBuilder.append(fullNativeBuilder);
14809        dropBuilder.append(fullJavaBuilder);
14810        dropBuilder.append('\n');
14811        dropBuilder.append(memInfoBuilder);
14812        dropBuilder.append('\n');
14813        /*
14814        dropBuilder.append(oomString);
14815        dropBuilder.append('\n');
14816        */
14817        StringWriter catSw = new StringWriter();
14818        synchronized (ActivityManagerService.this) {
14819            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14820            String[] emptyArgs = new String[] { };
14821            catPw.println();
14822            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14823            catPw.println();
14824            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14825                    false, false, null);
14826            catPw.println();
14827            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14828            catPw.flush();
14829        }
14830        dropBuilder.append(catSw.toString());
14831        addErrorToDropBox("lowmem", null, "system_server", null,
14832                null, tag.toString(), dropBuilder.toString(), null, null);
14833        //Slog.i(TAG, "Sent to dropbox:");
14834        //Slog.i(TAG, dropBuilder.toString());
14835        synchronized (ActivityManagerService.this) {
14836            long now = SystemClock.uptimeMillis();
14837            if (mLastMemUsageReportTime < now) {
14838                mLastMemUsageReportTime = now;
14839            }
14840        }
14841    }
14842
14843    /**
14844     * Searches array of arguments for the specified string
14845     * @param args array of argument strings
14846     * @param value value to search for
14847     * @return true if the value is contained in the array
14848     */
14849    private static boolean scanArgs(String[] args, String value) {
14850        if (args != null) {
14851            for (String arg : args) {
14852                if (value.equals(arg)) {
14853                    return true;
14854                }
14855            }
14856        }
14857        return false;
14858    }
14859
14860    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14861            ContentProviderRecord cpr, boolean always) {
14862        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14863
14864        if (!inLaunching || always) {
14865            synchronized (cpr) {
14866                cpr.launchingApp = null;
14867                cpr.notifyAll();
14868            }
14869            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14870            String names[] = cpr.info.authority.split(";");
14871            for (int j = 0; j < names.length; j++) {
14872                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14873            }
14874        }
14875
14876        for (int i=0; i<cpr.connections.size(); i++) {
14877            ContentProviderConnection conn = cpr.connections.get(i);
14878            if (conn.waiting) {
14879                // If this connection is waiting for the provider, then we don't
14880                // need to mess with its process unless we are always removing
14881                // or for some reason the provider is not currently launching.
14882                if (inLaunching && !always) {
14883                    continue;
14884                }
14885            }
14886            ProcessRecord capp = conn.client;
14887            conn.dead = true;
14888            if (conn.stableCount > 0) {
14889                if (!capp.persistent && capp.thread != null
14890                        && capp.pid != 0
14891                        && capp.pid != MY_PID) {
14892                    capp.kill("depends on provider "
14893                            + cpr.name.flattenToShortString()
14894                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14895                }
14896            } else if (capp.thread != null && conn.provider.provider != null) {
14897                try {
14898                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14899                } catch (RemoteException e) {
14900                }
14901                // In the protocol here, we don't expect the client to correctly
14902                // clean up this connection, we'll just remove it.
14903                cpr.connections.remove(i);
14904                if (conn.client.conProviders.remove(conn)) {
14905                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14906                }
14907            }
14908        }
14909
14910        if (inLaunching && always) {
14911            mLaunchingProviders.remove(cpr);
14912        }
14913        return inLaunching;
14914    }
14915
14916    /**
14917     * Main code for cleaning up a process when it has gone away.  This is
14918     * called both as a result of the process dying, or directly when stopping
14919     * a process when running in single process mode.
14920     *
14921     * @return Returns true if the given process has been restarted, so the
14922     * app that was passed in must remain on the process lists.
14923     */
14924    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14925            boolean restarting, boolean allowRestart, int index) {
14926        if (index >= 0) {
14927            removeLruProcessLocked(app);
14928            ProcessList.remove(app.pid);
14929        }
14930
14931        mProcessesToGc.remove(app);
14932        mPendingPssProcesses.remove(app);
14933
14934        // Dismiss any open dialogs.
14935        if (app.crashDialog != null && !app.forceCrashReport) {
14936            app.crashDialog.dismiss();
14937            app.crashDialog = null;
14938        }
14939        if (app.anrDialog != null) {
14940            app.anrDialog.dismiss();
14941            app.anrDialog = null;
14942        }
14943        if (app.waitDialog != null) {
14944            app.waitDialog.dismiss();
14945            app.waitDialog = null;
14946        }
14947
14948        app.crashing = false;
14949        app.notResponding = false;
14950
14951        app.resetPackageList(mProcessStats);
14952        app.unlinkDeathRecipient();
14953        app.makeInactive(mProcessStats);
14954        app.waitingToKill = null;
14955        app.forcingToForeground = null;
14956        updateProcessForegroundLocked(app, false, false);
14957        app.foregroundActivities = false;
14958        app.hasShownUi = false;
14959        app.treatLikeActivity = false;
14960        app.hasAboveClient = false;
14961        app.hasClientActivities = false;
14962
14963        mServices.killServicesLocked(app, allowRestart);
14964
14965        boolean restart = false;
14966
14967        // Remove published content providers.
14968        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14969            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14970            final boolean always = app.bad || !allowRestart;
14971            if (removeDyingProviderLocked(app, cpr, always) || always) {
14972                // We left the provider in the launching list, need to
14973                // restart it.
14974                restart = true;
14975            }
14976
14977            cpr.provider = null;
14978            cpr.proc = null;
14979        }
14980        app.pubProviders.clear();
14981
14982        // Take care of any launching providers waiting for this process.
14983        if (checkAppInLaunchingProvidersLocked(app, false)) {
14984            restart = true;
14985        }
14986
14987        // Unregister from connected content providers.
14988        if (!app.conProviders.isEmpty()) {
14989            for (int i=0; i<app.conProviders.size(); i++) {
14990                ContentProviderConnection conn = app.conProviders.get(i);
14991                conn.provider.connections.remove(conn);
14992                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14993                        conn.provider.name);
14994            }
14995            app.conProviders.clear();
14996        }
14997
14998        // At this point there may be remaining entries in mLaunchingProviders
14999        // where we were the only one waiting, so they are no longer of use.
15000        // Look for these and clean up if found.
15001        // XXX Commented out for now.  Trying to figure out a way to reproduce
15002        // the actual situation to identify what is actually going on.
15003        if (false) {
15004            for (int i=0; i<mLaunchingProviders.size(); i++) {
15005                ContentProviderRecord cpr = (ContentProviderRecord)
15006                        mLaunchingProviders.get(i);
15007                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15008                    synchronized (cpr) {
15009                        cpr.launchingApp = null;
15010                        cpr.notifyAll();
15011                    }
15012                }
15013            }
15014        }
15015
15016        skipCurrentReceiverLocked(app);
15017
15018        // Unregister any receivers.
15019        for (int i=app.receivers.size()-1; i>=0; i--) {
15020            removeReceiverLocked(app.receivers.valueAt(i));
15021        }
15022        app.receivers.clear();
15023
15024        // If the app is undergoing backup, tell the backup manager about it
15025        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15026            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
15027                    + mBackupTarget.appInfo + " died during backup");
15028            try {
15029                IBackupManager bm = IBackupManager.Stub.asInterface(
15030                        ServiceManager.getService(Context.BACKUP_SERVICE));
15031                bm.agentDisconnected(app.info.packageName);
15032            } catch (RemoteException e) {
15033                // can't happen; backup manager is local
15034            }
15035        }
15036
15037        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
15038            ProcessChangeItem item = mPendingProcessChanges.get(i);
15039            if (item.pid == app.pid) {
15040                mPendingProcessChanges.remove(i);
15041                mAvailProcessChanges.add(item);
15042            }
15043        }
15044        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15045
15046        // If the caller is restarting this app, then leave it in its
15047        // current lists and let the caller take care of it.
15048        if (restarting) {
15049            return false;
15050        }
15051
15052        if (!app.persistent || app.isolated) {
15053            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15054                    "Removing non-persistent process during cleanup: " + app);
15055            mProcessNames.remove(app.processName, app.uid);
15056            mIsolatedProcesses.remove(app.uid);
15057            if (mHeavyWeightProcess == app) {
15058                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15059                        mHeavyWeightProcess.userId, 0));
15060                mHeavyWeightProcess = null;
15061            }
15062        } else if (!app.removed) {
15063            // This app is persistent, so we need to keep its record around.
15064            // If it is not already on the pending app list, add it there
15065            // and start a new process for it.
15066            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15067                mPersistentStartingProcesses.add(app);
15068                restart = true;
15069            }
15070        }
15071        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15072                "Clean-up removing on hold: " + app);
15073        mProcessesOnHold.remove(app);
15074
15075        if (app == mHomeProcess) {
15076            mHomeProcess = null;
15077        }
15078        if (app == mPreviousProcess) {
15079            mPreviousProcess = null;
15080        }
15081
15082        if (restart && !app.isolated) {
15083            // We have components that still need to be running in the
15084            // process, so re-launch it.
15085            if (index < 0) {
15086                ProcessList.remove(app.pid);
15087            }
15088            mProcessNames.put(app.processName, app.uid, app);
15089            startProcessLocked(app, "restart", app.processName);
15090            return true;
15091        } else if (app.pid > 0 && app.pid != MY_PID) {
15092            // Goodbye!
15093            boolean removed;
15094            synchronized (mPidsSelfLocked) {
15095                mPidsSelfLocked.remove(app.pid);
15096                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15097            }
15098            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15099            if (app.isolated) {
15100                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15101            }
15102            app.setPid(0);
15103        }
15104        return false;
15105    }
15106
15107    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15108        // Look through the content providers we are waiting to have launched,
15109        // and if any run in this process then either schedule a restart of
15110        // the process or kill the client waiting for it if this process has
15111        // gone bad.
15112        int NL = mLaunchingProviders.size();
15113        boolean restart = false;
15114        for (int i=0; i<NL; i++) {
15115            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15116            if (cpr.launchingApp == app) {
15117                if (!alwaysBad && !app.bad) {
15118                    restart = true;
15119                } else {
15120                    removeDyingProviderLocked(app, cpr, true);
15121                    // cpr should have been removed from mLaunchingProviders
15122                    NL = mLaunchingProviders.size();
15123                    i--;
15124                }
15125            }
15126        }
15127        return restart;
15128    }
15129
15130    // =========================================================
15131    // SERVICES
15132    // =========================================================
15133
15134    @Override
15135    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15136            int flags) {
15137        enforceNotIsolatedCaller("getServices");
15138        synchronized (this) {
15139            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15140        }
15141    }
15142
15143    @Override
15144    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15145        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15146        synchronized (this) {
15147            return mServices.getRunningServiceControlPanelLocked(name);
15148        }
15149    }
15150
15151    @Override
15152    public ComponentName startService(IApplicationThread caller, Intent service,
15153            String resolvedType, int userId) {
15154        enforceNotIsolatedCaller("startService");
15155        // Refuse possible leaked file descriptors
15156        if (service != null && service.hasFileDescriptors() == true) {
15157            throw new IllegalArgumentException("File descriptors passed in Intent");
15158        }
15159
15160        if (DEBUG_SERVICE)
15161            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15162        synchronized(this) {
15163            final int callingPid = Binder.getCallingPid();
15164            final int callingUid = Binder.getCallingUid();
15165            final long origId = Binder.clearCallingIdentity();
15166            ComponentName res = mServices.startServiceLocked(caller, service,
15167                    resolvedType, callingPid, callingUid, userId);
15168            Binder.restoreCallingIdentity(origId);
15169            return res;
15170        }
15171    }
15172
15173    ComponentName startServiceInPackage(int uid,
15174            Intent service, String resolvedType, int userId) {
15175        synchronized(this) {
15176            if (DEBUG_SERVICE)
15177                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15178            final long origId = Binder.clearCallingIdentity();
15179            ComponentName res = mServices.startServiceLocked(null, service,
15180                    resolvedType, -1, uid, userId);
15181            Binder.restoreCallingIdentity(origId);
15182            return res;
15183        }
15184    }
15185
15186    @Override
15187    public int stopService(IApplicationThread caller, Intent service,
15188            String resolvedType, int userId) {
15189        enforceNotIsolatedCaller("stopService");
15190        // Refuse possible leaked file descriptors
15191        if (service != null && service.hasFileDescriptors() == true) {
15192            throw new IllegalArgumentException("File descriptors passed in Intent");
15193        }
15194
15195        synchronized(this) {
15196            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15197        }
15198    }
15199
15200    @Override
15201    public IBinder peekService(Intent service, String resolvedType) {
15202        enforceNotIsolatedCaller("peekService");
15203        // Refuse possible leaked file descriptors
15204        if (service != null && service.hasFileDescriptors() == true) {
15205            throw new IllegalArgumentException("File descriptors passed in Intent");
15206        }
15207        synchronized(this) {
15208            return mServices.peekServiceLocked(service, resolvedType);
15209        }
15210    }
15211
15212    @Override
15213    public boolean stopServiceToken(ComponentName className, IBinder token,
15214            int startId) {
15215        synchronized(this) {
15216            return mServices.stopServiceTokenLocked(className, token, startId);
15217        }
15218    }
15219
15220    @Override
15221    public void setServiceForeground(ComponentName className, IBinder token,
15222            int id, Notification notification, boolean removeNotification) {
15223        synchronized(this) {
15224            mServices.setServiceForegroundLocked(className, token, id, notification,
15225                    removeNotification);
15226        }
15227    }
15228
15229    @Override
15230    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15231            boolean requireFull, String name, String callerPackage) {
15232        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15233                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15234    }
15235
15236    int unsafeConvertIncomingUser(int userId) {
15237        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15238                ? mCurrentUserId : userId;
15239    }
15240
15241    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15242            int allowMode, String name, String callerPackage) {
15243        final int callingUserId = UserHandle.getUserId(callingUid);
15244        if (callingUserId == userId) {
15245            return userId;
15246        }
15247
15248        // Note that we may be accessing mCurrentUserId outside of a lock...
15249        // shouldn't be a big deal, if this is being called outside
15250        // of a locked context there is intrinsically a race with
15251        // the value the caller will receive and someone else changing it.
15252        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15253        // we will switch to the calling user if access to the current user fails.
15254        int targetUserId = unsafeConvertIncomingUser(userId);
15255
15256        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15257            final boolean allow;
15258            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15259                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15260                // If the caller has this permission, they always pass go.  And collect $200.
15261                allow = true;
15262            } else if (allowMode == ALLOW_FULL_ONLY) {
15263                // We require full access, sucks to be you.
15264                allow = false;
15265            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15266                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15267                // If the caller does not have either permission, they are always doomed.
15268                allow = false;
15269            } else if (allowMode == ALLOW_NON_FULL) {
15270                // We are blanket allowing non-full access, you lucky caller!
15271                allow = true;
15272            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15273                // We may or may not allow this depending on whether the two users are
15274                // in the same profile.
15275                synchronized (mUserProfileGroupIdsSelfLocked) {
15276                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15277                            UserInfo.NO_PROFILE_GROUP_ID);
15278                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15279                            UserInfo.NO_PROFILE_GROUP_ID);
15280                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15281                            && callingProfile == targetProfile;
15282                }
15283            } else {
15284                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15285            }
15286            if (!allow) {
15287                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15288                    // In this case, they would like to just execute as their
15289                    // owner user instead of failing.
15290                    targetUserId = callingUserId;
15291                } else {
15292                    StringBuilder builder = new StringBuilder(128);
15293                    builder.append("Permission Denial: ");
15294                    builder.append(name);
15295                    if (callerPackage != null) {
15296                        builder.append(" from ");
15297                        builder.append(callerPackage);
15298                    }
15299                    builder.append(" asks to run as user ");
15300                    builder.append(userId);
15301                    builder.append(" but is calling from user ");
15302                    builder.append(UserHandle.getUserId(callingUid));
15303                    builder.append("; this requires ");
15304                    builder.append(INTERACT_ACROSS_USERS_FULL);
15305                    if (allowMode != ALLOW_FULL_ONLY) {
15306                        builder.append(" or ");
15307                        builder.append(INTERACT_ACROSS_USERS);
15308                    }
15309                    String msg = builder.toString();
15310                    Slog.w(TAG, msg);
15311                    throw new SecurityException(msg);
15312                }
15313            }
15314        }
15315        if (!allowAll && targetUserId < 0) {
15316            throw new IllegalArgumentException(
15317                    "Call does not support special user #" + targetUserId);
15318        }
15319        // Check shell permission
15320        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15321            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15322                    targetUserId)) {
15323                throw new SecurityException("Shell does not have permission to access user "
15324                        + targetUserId + "\n " + Debug.getCallers(3));
15325            }
15326        }
15327        return targetUserId;
15328    }
15329
15330    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15331            String className, int flags) {
15332        boolean result = false;
15333        // For apps that don't have pre-defined UIDs, check for permission
15334        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15335            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15336                if (ActivityManager.checkUidPermission(
15337                        INTERACT_ACROSS_USERS,
15338                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15339                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15340                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15341                            + " requests FLAG_SINGLE_USER, but app does not hold "
15342                            + INTERACT_ACROSS_USERS;
15343                    Slog.w(TAG, msg);
15344                    throw new SecurityException(msg);
15345                }
15346                // Permission passed
15347                result = true;
15348            }
15349        } else if ("system".equals(componentProcessName)) {
15350            result = true;
15351        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15352            // Phone app and persistent apps are allowed to export singleuser providers.
15353            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15354                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15355        }
15356        if (DEBUG_MU) {
15357            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15358                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15359        }
15360        return result;
15361    }
15362
15363    /**
15364     * Checks to see if the caller is in the same app as the singleton
15365     * component, or the component is in a special app. It allows special apps
15366     * to export singleton components but prevents exporting singleton
15367     * components for regular apps.
15368     */
15369    boolean isValidSingletonCall(int callingUid, int componentUid) {
15370        int componentAppId = UserHandle.getAppId(componentUid);
15371        return UserHandle.isSameApp(callingUid, componentUid)
15372                || componentAppId == Process.SYSTEM_UID
15373                || componentAppId == Process.PHONE_UID
15374                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15375                        == PackageManager.PERMISSION_GRANTED;
15376    }
15377
15378    public int bindService(IApplicationThread caller, IBinder token,
15379            Intent service, String resolvedType,
15380            IServiceConnection connection, int flags, int userId) {
15381        enforceNotIsolatedCaller("bindService");
15382
15383        // Refuse possible leaked file descriptors
15384        if (service != null && service.hasFileDescriptors() == true) {
15385            throw new IllegalArgumentException("File descriptors passed in Intent");
15386        }
15387
15388        synchronized(this) {
15389            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15390                    connection, flags, userId);
15391        }
15392    }
15393
15394    public boolean unbindService(IServiceConnection connection) {
15395        synchronized (this) {
15396            return mServices.unbindServiceLocked(connection);
15397        }
15398    }
15399
15400    public void publishService(IBinder token, Intent intent, IBinder service) {
15401        // Refuse possible leaked file descriptors
15402        if (intent != null && intent.hasFileDescriptors() == true) {
15403            throw new IllegalArgumentException("File descriptors passed in Intent");
15404        }
15405
15406        synchronized(this) {
15407            if (!(token instanceof ServiceRecord)) {
15408                throw new IllegalArgumentException("Invalid service token");
15409            }
15410            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15411        }
15412    }
15413
15414    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15415        // Refuse possible leaked file descriptors
15416        if (intent != null && intent.hasFileDescriptors() == true) {
15417            throw new IllegalArgumentException("File descriptors passed in Intent");
15418        }
15419
15420        synchronized(this) {
15421            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15422        }
15423    }
15424
15425    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15426        synchronized(this) {
15427            if (!(token instanceof ServiceRecord)) {
15428                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15429                throw new IllegalArgumentException("Invalid service token");
15430            }
15431            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15432        }
15433    }
15434
15435    // =========================================================
15436    // BACKUP AND RESTORE
15437    // =========================================================
15438
15439    // Cause the target app to be launched if necessary and its backup agent
15440    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15441    // activity manager to announce its creation.
15442    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15443        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15444        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15445
15446        synchronized(this) {
15447            // !!! TODO: currently no check here that we're already bound
15448            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15449            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15450            synchronized (stats) {
15451                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15452            }
15453
15454            // Backup agent is now in use, its package can't be stopped.
15455            try {
15456                AppGlobals.getPackageManager().setPackageStoppedState(
15457                        app.packageName, false, UserHandle.getUserId(app.uid));
15458            } catch (RemoteException e) {
15459            } catch (IllegalArgumentException e) {
15460                Slog.w(TAG, "Failed trying to unstop package "
15461                        + app.packageName + ": " + e);
15462            }
15463
15464            BackupRecord r = new BackupRecord(ss, app, backupMode);
15465            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15466                    ? new ComponentName(app.packageName, app.backupAgentName)
15467                    : new ComponentName("android", "FullBackupAgent");
15468            // startProcessLocked() returns existing proc's record if it's already running
15469            ProcessRecord proc = startProcessLocked(app.processName, app,
15470                    false, 0, "backup", hostingName, false, false, false);
15471            if (proc == null) {
15472                Slog.e(TAG, "Unable to start backup agent process " + r);
15473                return false;
15474            }
15475
15476            r.app = proc;
15477            mBackupTarget = r;
15478            mBackupAppName = app.packageName;
15479
15480            // Try not to kill the process during backup
15481            updateOomAdjLocked(proc);
15482
15483            // If the process is already attached, schedule the creation of the backup agent now.
15484            // If it is not yet live, this will be done when it attaches to the framework.
15485            if (proc.thread != null) {
15486                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15487                try {
15488                    proc.thread.scheduleCreateBackupAgent(app,
15489                            compatibilityInfoForPackageLocked(app), backupMode);
15490                } catch (RemoteException e) {
15491                    // Will time out on the backup manager side
15492                }
15493            } else {
15494                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15495            }
15496            // Invariants: at this point, the target app process exists and the application
15497            // is either already running or in the process of coming up.  mBackupTarget and
15498            // mBackupAppName describe the app, so that when it binds back to the AM we
15499            // know that it's scheduled for a backup-agent operation.
15500        }
15501
15502        return true;
15503    }
15504
15505    @Override
15506    public void clearPendingBackup() {
15507        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15508        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15509
15510        synchronized (this) {
15511            mBackupTarget = null;
15512            mBackupAppName = null;
15513        }
15514    }
15515
15516    // A backup agent has just come up
15517    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15518        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15519                + " = " + agent);
15520
15521        synchronized(this) {
15522            if (!agentPackageName.equals(mBackupAppName)) {
15523                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15524                return;
15525            }
15526        }
15527
15528        long oldIdent = Binder.clearCallingIdentity();
15529        try {
15530            IBackupManager bm = IBackupManager.Stub.asInterface(
15531                    ServiceManager.getService(Context.BACKUP_SERVICE));
15532            bm.agentConnected(agentPackageName, agent);
15533        } catch (RemoteException e) {
15534            // can't happen; the backup manager service is local
15535        } catch (Exception e) {
15536            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15537            e.printStackTrace();
15538        } finally {
15539            Binder.restoreCallingIdentity(oldIdent);
15540        }
15541    }
15542
15543    // done with this agent
15544    public void unbindBackupAgent(ApplicationInfo appInfo) {
15545        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15546        if (appInfo == null) {
15547            Slog.w(TAG, "unbind backup agent for null app");
15548            return;
15549        }
15550
15551        synchronized(this) {
15552            try {
15553                if (mBackupAppName == null) {
15554                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15555                    return;
15556                }
15557
15558                if (!mBackupAppName.equals(appInfo.packageName)) {
15559                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15560                    return;
15561                }
15562
15563                // Not backing this app up any more; reset its OOM adjustment
15564                final ProcessRecord proc = mBackupTarget.app;
15565                updateOomAdjLocked(proc);
15566
15567                // If the app crashed during backup, 'thread' will be null here
15568                if (proc.thread != null) {
15569                    try {
15570                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15571                                compatibilityInfoForPackageLocked(appInfo));
15572                    } catch (Exception e) {
15573                        Slog.e(TAG, "Exception when unbinding backup agent:");
15574                        e.printStackTrace();
15575                    }
15576                }
15577            } finally {
15578                mBackupTarget = null;
15579                mBackupAppName = null;
15580            }
15581        }
15582    }
15583    // =========================================================
15584    // BROADCASTS
15585    // =========================================================
15586
15587    boolean isPendingBroadcastProcessLocked(int pid) {
15588        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15589                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15590    }
15591
15592    void skipPendingBroadcastLocked(int pid) {
15593            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15594            for (BroadcastQueue queue : mBroadcastQueues) {
15595                queue.skipPendingBroadcastLocked(pid);
15596            }
15597    }
15598
15599    // The app just attached; send any pending broadcasts that it should receive
15600    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15601        boolean didSomething = false;
15602        for (BroadcastQueue queue : mBroadcastQueues) {
15603            didSomething |= queue.sendPendingBroadcastsLocked(app);
15604        }
15605        return didSomething;
15606    }
15607
15608    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15609            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15610        enforceNotIsolatedCaller("registerReceiver");
15611        ArrayList<Intent> stickyIntents = null;
15612        ProcessRecord callerApp = null;
15613        int callingUid;
15614        int callingPid;
15615        synchronized(this) {
15616            if (caller != null) {
15617                callerApp = getRecordForAppLocked(caller);
15618                if (callerApp == null) {
15619                    throw new SecurityException(
15620                            "Unable to find app for caller " + caller
15621                            + " (pid=" + Binder.getCallingPid()
15622                            + ") when registering receiver " + receiver);
15623                }
15624                if (callerApp.info.uid != Process.SYSTEM_UID &&
15625                        !callerApp.pkgList.containsKey(callerPackage) &&
15626                        !"android".equals(callerPackage)) {
15627                    throw new SecurityException("Given caller package " + callerPackage
15628                            + " is not running in process " + callerApp);
15629                }
15630                callingUid = callerApp.info.uid;
15631                callingPid = callerApp.pid;
15632            } else {
15633                callerPackage = null;
15634                callingUid = Binder.getCallingUid();
15635                callingPid = Binder.getCallingPid();
15636            }
15637
15638            userId = handleIncomingUser(callingPid, callingUid, userId,
15639                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15640
15641            Iterator<String> actions = filter.actionsIterator();
15642            if (actions == null) {
15643                ArrayList<String> noAction = new ArrayList<String>(1);
15644                noAction.add(null);
15645                actions = noAction.iterator();
15646            }
15647
15648            // Collect stickies of users
15649            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15650            while (actions.hasNext()) {
15651                String action = actions.next();
15652                for (int id : userIds) {
15653                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15654                    if (stickies != null) {
15655                        ArrayList<Intent> intents = stickies.get(action);
15656                        if (intents != null) {
15657                            if (stickyIntents == null) {
15658                                stickyIntents = new ArrayList<Intent>();
15659                            }
15660                            stickyIntents.addAll(intents);
15661                        }
15662                    }
15663                }
15664            }
15665        }
15666
15667        ArrayList<Intent> allSticky = null;
15668        if (stickyIntents != null) {
15669            final ContentResolver resolver = mContext.getContentResolver();
15670            // Look for any matching sticky broadcasts...
15671            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15672                Intent intent = stickyIntents.get(i);
15673                // If intent has scheme "content", it will need to acccess
15674                // provider that needs to lock mProviderMap in ActivityThread
15675                // and also it may need to wait application response, so we
15676                // cannot lock ActivityManagerService here.
15677                if (filter.match(resolver, intent, true, TAG) >= 0) {
15678                    if (allSticky == null) {
15679                        allSticky = new ArrayList<Intent>();
15680                    }
15681                    allSticky.add(intent);
15682                }
15683            }
15684        }
15685
15686        // The first sticky in the list is returned directly back to the client.
15687        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15688        if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
15689        if (receiver == null) {
15690            return sticky;
15691        }
15692
15693        synchronized (this) {
15694            if (callerApp != null && callerApp.pid == 0) {
15695                // Caller already died
15696                return null;
15697            }
15698            ReceiverList rl
15699                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15700            if (rl == null) {
15701                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15702                        userId, receiver);
15703                if (rl.app != null) {
15704                    rl.app.receivers.add(rl);
15705                } else {
15706                    try {
15707                        receiver.asBinder().linkToDeath(rl, 0);
15708                    } catch (RemoteException e) {
15709                        return sticky;
15710                    }
15711                    rl.linkedToDeath = true;
15712                }
15713                mRegisteredReceivers.put(receiver.asBinder(), rl);
15714            } else if (rl.uid != callingUid) {
15715                throw new IllegalArgumentException(
15716                        "Receiver requested to register for uid " + callingUid
15717                        + " was previously registered for uid " + rl.uid);
15718            } else if (rl.pid != callingPid) {
15719                throw new IllegalArgumentException(
15720                        "Receiver requested to register for pid " + callingPid
15721                        + " was previously registered for pid " + rl.pid);
15722            } else if (rl.userId != userId) {
15723                throw new IllegalArgumentException(
15724                        "Receiver requested to register for user " + userId
15725                        + " was previously registered for user " + rl.userId);
15726            }
15727            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15728                    permission, callingUid, userId);
15729            rl.add(bf);
15730            if (!bf.debugCheck()) {
15731                Slog.w(TAG, "==> For Dynamic broadast");
15732            }
15733            mReceiverResolver.addFilter(bf);
15734
15735            // Enqueue broadcasts for all existing stickies that match
15736            // this filter.
15737            if (allSticky != null) {
15738                ArrayList receivers = new ArrayList();
15739                receivers.add(bf);
15740
15741                int N = allSticky.size();
15742                for (int i=0; i<N; i++) {
15743                    Intent intent = (Intent)allSticky.get(i);
15744                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15745                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15746                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15747                            null, null, false, true, true, -1);
15748                    queue.enqueueParallelBroadcastLocked(r);
15749                    queue.scheduleBroadcastsLocked();
15750                }
15751            }
15752
15753            return sticky;
15754        }
15755    }
15756
15757    public void unregisterReceiver(IIntentReceiver receiver) {
15758        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15759
15760        final long origId = Binder.clearCallingIdentity();
15761        try {
15762            boolean doTrim = false;
15763
15764            synchronized(this) {
15765                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15766                if (rl != null) {
15767                    final BroadcastRecord r = rl.curBroadcast;
15768                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15769                        final boolean doNext = r.queue.finishReceiverLocked(
15770                                r, r.resultCode, r.resultData, r.resultExtras,
15771                                r.resultAbort, false);
15772                        if (doNext) {
15773                            doTrim = true;
15774                            r.queue.processNextBroadcast(false);
15775                        }
15776                    }
15777
15778                    if (rl.app != null) {
15779                        rl.app.receivers.remove(rl);
15780                    }
15781                    removeReceiverLocked(rl);
15782                    if (rl.linkedToDeath) {
15783                        rl.linkedToDeath = false;
15784                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15785                    }
15786                }
15787            }
15788
15789            // If we actually concluded any broadcasts, we might now be able
15790            // to trim the recipients' apps from our working set
15791            if (doTrim) {
15792                trimApplications();
15793                return;
15794            }
15795
15796        } finally {
15797            Binder.restoreCallingIdentity(origId);
15798        }
15799    }
15800
15801    void removeReceiverLocked(ReceiverList rl) {
15802        mRegisteredReceivers.remove(rl.receiver.asBinder());
15803        int N = rl.size();
15804        for (int i=0; i<N; i++) {
15805            mReceiverResolver.removeFilter(rl.get(i));
15806        }
15807    }
15808
15809    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15810        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15811            ProcessRecord r = mLruProcesses.get(i);
15812            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15813                try {
15814                    r.thread.dispatchPackageBroadcast(cmd, packages);
15815                } catch (RemoteException ex) {
15816                }
15817            }
15818        }
15819    }
15820
15821    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15822            int callingUid, int[] users) {
15823        List<ResolveInfo> receivers = null;
15824        try {
15825            HashSet<ComponentName> singleUserReceivers = null;
15826            boolean scannedFirstReceivers = false;
15827            for (int user : users) {
15828                // Skip users that have Shell restrictions
15829                if (callingUid == Process.SHELL_UID
15830                        && getUserManagerLocked().hasUserRestriction(
15831                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15832                    continue;
15833                }
15834                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15835                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15836                if (user != 0 && newReceivers != null) {
15837                    // If this is not the primary user, we need to check for
15838                    // any receivers that should be filtered out.
15839                    for (int i=0; i<newReceivers.size(); i++) {
15840                        ResolveInfo ri = newReceivers.get(i);
15841                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15842                            newReceivers.remove(i);
15843                            i--;
15844                        }
15845                    }
15846                }
15847                if (newReceivers != null && newReceivers.size() == 0) {
15848                    newReceivers = null;
15849                }
15850                if (receivers == null) {
15851                    receivers = newReceivers;
15852                } else if (newReceivers != null) {
15853                    // We need to concatenate the additional receivers
15854                    // found with what we have do far.  This would be easy,
15855                    // but we also need to de-dup any receivers that are
15856                    // singleUser.
15857                    if (!scannedFirstReceivers) {
15858                        // Collect any single user receivers we had already retrieved.
15859                        scannedFirstReceivers = true;
15860                        for (int i=0; i<receivers.size(); i++) {
15861                            ResolveInfo ri = receivers.get(i);
15862                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15863                                ComponentName cn = new ComponentName(
15864                                        ri.activityInfo.packageName, ri.activityInfo.name);
15865                                if (singleUserReceivers == null) {
15866                                    singleUserReceivers = new HashSet<ComponentName>();
15867                                }
15868                                singleUserReceivers.add(cn);
15869                            }
15870                        }
15871                    }
15872                    // Add the new results to the existing results, tracking
15873                    // and de-dupping single user receivers.
15874                    for (int i=0; i<newReceivers.size(); i++) {
15875                        ResolveInfo ri = newReceivers.get(i);
15876                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15877                            ComponentName cn = new ComponentName(
15878                                    ri.activityInfo.packageName, ri.activityInfo.name);
15879                            if (singleUserReceivers == null) {
15880                                singleUserReceivers = new HashSet<ComponentName>();
15881                            }
15882                            if (!singleUserReceivers.contains(cn)) {
15883                                singleUserReceivers.add(cn);
15884                                receivers.add(ri);
15885                            }
15886                        } else {
15887                            receivers.add(ri);
15888                        }
15889                    }
15890                }
15891            }
15892        } catch (RemoteException ex) {
15893            // pm is in same process, this will never happen.
15894        }
15895        return receivers;
15896    }
15897
15898    private final int broadcastIntentLocked(ProcessRecord callerApp,
15899            String callerPackage, Intent intent, String resolvedType,
15900            IIntentReceiver resultTo, int resultCode, String resultData,
15901            Bundle map, String requiredPermission, int appOp,
15902            boolean ordered, boolean sticky, int callingPid, int callingUid,
15903            int userId) {
15904        intent = new Intent(intent);
15905
15906        // By default broadcasts do not go to stopped apps.
15907        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15908
15909        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15910            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15911            + " ordered=" + ordered + " userid=" + userId);
15912        if ((resultTo != null) && !ordered) {
15913            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15914        }
15915
15916        userId = handleIncomingUser(callingPid, callingUid, userId,
15917                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15918
15919        // Make sure that the user who is receiving this broadcast is running.
15920        // If not, we will just skip it. Make an exception for shutdown broadcasts
15921        // and upgrade steps.
15922
15923        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15924            if ((callingUid != Process.SYSTEM_UID
15925                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15926                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15927                Slog.w(TAG, "Skipping broadcast of " + intent
15928                        + ": user " + userId + " is stopped");
15929                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15930            }
15931        }
15932
15933        /*
15934         * Prevent non-system code (defined here to be non-persistent
15935         * processes) from sending protected broadcasts.
15936         */
15937        int callingAppId = UserHandle.getAppId(callingUid);
15938        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15939            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15940            || callingAppId == Process.NFC_UID || callingUid == 0) {
15941            // Always okay.
15942        } else if (callerApp == null || !callerApp.persistent) {
15943            try {
15944                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15945                        intent.getAction())) {
15946                    String msg = "Permission Denial: not allowed to send broadcast "
15947                            + intent.getAction() + " from pid="
15948                            + callingPid + ", uid=" + callingUid;
15949                    Slog.w(TAG, msg);
15950                    throw new SecurityException(msg);
15951                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15952                    // Special case for compatibility: we don't want apps to send this,
15953                    // but historically it has not been protected and apps may be using it
15954                    // to poke their own app widget.  So, instead of making it protected,
15955                    // just limit it to the caller.
15956                    if (callerApp == null) {
15957                        String msg = "Permission Denial: not allowed to send broadcast "
15958                                + intent.getAction() + " from unknown caller.";
15959                        Slog.w(TAG, msg);
15960                        throw new SecurityException(msg);
15961                    } else if (intent.getComponent() != null) {
15962                        // They are good enough to send to an explicit component...  verify
15963                        // it is being sent to the calling app.
15964                        if (!intent.getComponent().getPackageName().equals(
15965                                callerApp.info.packageName)) {
15966                            String msg = "Permission Denial: not allowed to send broadcast "
15967                                    + intent.getAction() + " to "
15968                                    + intent.getComponent().getPackageName() + " from "
15969                                    + callerApp.info.packageName;
15970                            Slog.w(TAG, msg);
15971                            throw new SecurityException(msg);
15972                        }
15973                    } else {
15974                        // Limit broadcast to their own package.
15975                        intent.setPackage(callerApp.info.packageName);
15976                    }
15977                }
15978            } catch (RemoteException e) {
15979                Slog.w(TAG, "Remote exception", e);
15980                return ActivityManager.BROADCAST_SUCCESS;
15981            }
15982        }
15983
15984        final String action = intent.getAction();
15985        if (action != null) {
15986            switch (action) {
15987                case Intent.ACTION_UID_REMOVED:
15988                case Intent.ACTION_PACKAGE_REMOVED:
15989                case Intent.ACTION_PACKAGE_CHANGED:
15990                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15991                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15992                    // Handle special intents: if this broadcast is from the package
15993                    // manager about a package being removed, we need to remove all of
15994                    // its activities from the history stack.
15995                    if (checkComponentPermission(
15996                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15997                            callingPid, callingUid, -1, true)
15998                            != PackageManager.PERMISSION_GRANTED) {
15999                        String msg = "Permission Denial: " + intent.getAction()
16000                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16001                                + ", uid=" + callingUid + ")"
16002                                + " requires "
16003                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16004                        Slog.w(TAG, msg);
16005                        throw new SecurityException(msg);
16006                    }
16007                    switch (action) {
16008                        case Intent.ACTION_UID_REMOVED:
16009                            final Bundle intentExtras = intent.getExtras();
16010                            final int uid = intentExtras != null
16011                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16012                            if (uid >= 0) {
16013                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
16014                                synchronized (bs) {
16015                                    bs.removeUidStatsLocked(uid);
16016                                }
16017                                mAppOpsService.uidRemoved(uid);
16018                            }
16019                            break;
16020                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16021                            // If resources are unavailable just force stop all those packages
16022                            // and flush the attribute cache as well.
16023                            String list[] =
16024                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16025                            if (list != null && list.length > 0) {
16026                                for (int i = 0; i < list.length; i++) {
16027                                    forceStopPackageLocked(list[i], -1, false, true, true,
16028                                            false, false, userId, "storage unmount");
16029                                }
16030                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
16031                                sendPackageBroadcastLocked(
16032                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16033                                        userId);
16034                            }
16035                            break;
16036                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16037                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
16038                            break;
16039                        case Intent.ACTION_PACKAGE_REMOVED:
16040                        case Intent.ACTION_PACKAGE_CHANGED:
16041                            Uri data = intent.getData();
16042                            String ssp;
16043                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16044                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16045                                boolean fullUninstall = removed &&
16046                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16047                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16048                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16049                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16050                                            false, true, true, false, fullUninstall, userId,
16051                                            removed ? "pkg removed" : "pkg changed");
16052                                }
16053                                if (removed) {
16054                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16055                                            new String[] {ssp}, userId);
16056                                    if (fullUninstall) {
16057                                        mAppOpsService.packageRemoved(
16058                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16059
16060                                        // Remove all permissions granted from/to this package
16061                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16062
16063                                        removeTasksByPackageNameLocked(ssp, userId);
16064                                        if (userId == UserHandle.USER_OWNER) {
16065                                            mTaskPersister.removeFromPackageCache(ssp);
16066                                        }
16067                                    }
16068                                } else {
16069                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16070                                    if (userId == UserHandle.USER_OWNER) {
16071                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16072                                    }
16073                                }
16074                            }
16075                            break;
16076                    }
16077                    break;
16078                case Intent.ACTION_PACKAGE_ADDED:
16079                    // Special case for adding a package: by default turn on compatibility mode.
16080                    Uri data = intent.getData();
16081                    String ssp;
16082                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16083                        final boolean replacing =
16084                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16085                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16086
16087                        if (replacing) {
16088                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16089                        }
16090                        if (userId == UserHandle.USER_OWNER) {
16091                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16092                        }
16093                    }
16094                    break;
16095                case Intent.ACTION_TIMEZONE_CHANGED:
16096                    // If this is the time zone changed action, queue up a message that will reset
16097                    // the timezone of all currently running processes. This message will get
16098                    // queued up before the broadcast happens.
16099                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16100                    break;
16101                case Intent.ACTION_TIME_CHANGED:
16102                    // If the user set the time, let all running processes know.
16103                    final int is24Hour =
16104                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16105                                    : 0;
16106                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16107                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16108                    synchronized (stats) {
16109                        stats.noteCurrentTimeChangedLocked();
16110                    }
16111                    break;
16112                case Intent.ACTION_CLEAR_DNS_CACHE:
16113                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16114                    break;
16115                case Proxy.PROXY_CHANGE_ACTION:
16116                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16117                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16118                    break;
16119            }
16120        }
16121
16122        // Add to the sticky list if requested.
16123        if (sticky) {
16124            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16125                    callingPid, callingUid)
16126                    != PackageManager.PERMISSION_GRANTED) {
16127                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16128                        + callingPid + ", uid=" + callingUid
16129                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16130                Slog.w(TAG, msg);
16131                throw new SecurityException(msg);
16132            }
16133            if (requiredPermission != null) {
16134                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16135                        + " and enforce permission " + requiredPermission);
16136                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16137            }
16138            if (intent.getComponent() != null) {
16139                throw new SecurityException(
16140                        "Sticky broadcasts can't target a specific component");
16141            }
16142            // We use userId directly here, since the "all" target is maintained
16143            // as a separate set of sticky broadcasts.
16144            if (userId != UserHandle.USER_ALL) {
16145                // But first, if this is not a broadcast to all users, then
16146                // make sure it doesn't conflict with an existing broadcast to
16147                // all users.
16148                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16149                        UserHandle.USER_ALL);
16150                if (stickies != null) {
16151                    ArrayList<Intent> list = stickies.get(intent.getAction());
16152                    if (list != null) {
16153                        int N = list.size();
16154                        int i;
16155                        for (i=0; i<N; i++) {
16156                            if (intent.filterEquals(list.get(i))) {
16157                                throw new IllegalArgumentException(
16158                                        "Sticky broadcast " + intent + " for user "
16159                                        + userId + " conflicts with existing global broadcast");
16160                            }
16161                        }
16162                    }
16163                }
16164            }
16165            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16166            if (stickies == null) {
16167                stickies = new ArrayMap<String, ArrayList<Intent>>();
16168                mStickyBroadcasts.put(userId, stickies);
16169            }
16170            ArrayList<Intent> list = stickies.get(intent.getAction());
16171            if (list == null) {
16172                list = new ArrayList<Intent>();
16173                stickies.put(intent.getAction(), list);
16174            }
16175            int N = list.size();
16176            int i;
16177            for (i=0; i<N; i++) {
16178                if (intent.filterEquals(list.get(i))) {
16179                    // This sticky already exists, replace it.
16180                    list.set(i, new Intent(intent));
16181                    break;
16182                }
16183            }
16184            if (i >= N) {
16185                list.add(new Intent(intent));
16186            }
16187        }
16188
16189        int[] users;
16190        if (userId == UserHandle.USER_ALL) {
16191            // Caller wants broadcast to go to all started users.
16192            users = mStartedUserArray;
16193        } else {
16194            // Caller wants broadcast to go to one specific user.
16195            users = new int[] {userId};
16196        }
16197
16198        // Figure out who all will receive this broadcast.
16199        List receivers = null;
16200        List<BroadcastFilter> registeredReceivers = null;
16201        // Need to resolve the intent to interested receivers...
16202        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16203                 == 0) {
16204            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16205        }
16206        if (intent.getComponent() == null) {
16207            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16208                // Query one target user at a time, excluding shell-restricted users
16209                UserManagerService ums = getUserManagerLocked();
16210                for (int i = 0; i < users.length; i++) {
16211                    if (ums.hasUserRestriction(
16212                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16213                        continue;
16214                    }
16215                    List<BroadcastFilter> registeredReceiversForUser =
16216                            mReceiverResolver.queryIntent(intent,
16217                                    resolvedType, false, users[i]);
16218                    if (registeredReceivers == null) {
16219                        registeredReceivers = registeredReceiversForUser;
16220                    } else if (registeredReceiversForUser != null) {
16221                        registeredReceivers.addAll(registeredReceiversForUser);
16222                    }
16223                }
16224            } else {
16225                registeredReceivers = mReceiverResolver.queryIntent(intent,
16226                        resolvedType, false, userId);
16227            }
16228        }
16229
16230        final boolean replacePending =
16231                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16232
16233        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16234                + " replacePending=" + replacePending);
16235
16236        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16237        if (!ordered && NR > 0) {
16238            // If we are not serializing this broadcast, then send the
16239            // registered receivers separately so they don't wait for the
16240            // components to be launched.
16241            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16242            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16243                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16244                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16245                    ordered, sticky, false, userId);
16246            if (DEBUG_BROADCAST) Slog.v(
16247                    TAG, "Enqueueing parallel broadcast " + r);
16248            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16249            if (!replaced) {
16250                queue.enqueueParallelBroadcastLocked(r);
16251                queue.scheduleBroadcastsLocked();
16252            }
16253            registeredReceivers = null;
16254            NR = 0;
16255        }
16256
16257        // Merge into one list.
16258        int ir = 0;
16259        if (receivers != null) {
16260            // A special case for PACKAGE_ADDED: do not allow the package
16261            // being added to see this broadcast.  This prevents them from
16262            // using this as a back door to get run as soon as they are
16263            // installed.  Maybe in the future we want to have a special install
16264            // broadcast or such for apps, but we'd like to deliberately make
16265            // this decision.
16266            String skipPackages[] = null;
16267            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16268                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16269                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16270                Uri data = intent.getData();
16271                if (data != null) {
16272                    String pkgName = data.getSchemeSpecificPart();
16273                    if (pkgName != null) {
16274                        skipPackages = new String[] { pkgName };
16275                    }
16276                }
16277            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16278                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16279            }
16280            if (skipPackages != null && (skipPackages.length > 0)) {
16281                for (String skipPackage : skipPackages) {
16282                    if (skipPackage != null) {
16283                        int NT = receivers.size();
16284                        for (int it=0; it<NT; it++) {
16285                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16286                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16287                                receivers.remove(it);
16288                                it--;
16289                                NT--;
16290                            }
16291                        }
16292                    }
16293                }
16294            }
16295
16296            int NT = receivers != null ? receivers.size() : 0;
16297            int it = 0;
16298            ResolveInfo curt = null;
16299            BroadcastFilter curr = null;
16300            while (it < NT && ir < NR) {
16301                if (curt == null) {
16302                    curt = (ResolveInfo)receivers.get(it);
16303                }
16304                if (curr == null) {
16305                    curr = registeredReceivers.get(ir);
16306                }
16307                if (curr.getPriority() >= curt.priority) {
16308                    // Insert this broadcast record into the final list.
16309                    receivers.add(it, curr);
16310                    ir++;
16311                    curr = null;
16312                    it++;
16313                    NT++;
16314                } else {
16315                    // Skip to the next ResolveInfo in the final list.
16316                    it++;
16317                    curt = null;
16318                }
16319            }
16320        }
16321        while (ir < NR) {
16322            if (receivers == null) {
16323                receivers = new ArrayList();
16324            }
16325            receivers.add(registeredReceivers.get(ir));
16326            ir++;
16327        }
16328
16329        if ((receivers != null && receivers.size() > 0)
16330                || resultTo != null) {
16331            BroadcastQueue queue = broadcastQueueForIntent(intent);
16332            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16333                    callerPackage, callingPid, callingUid, resolvedType,
16334                    requiredPermission, appOp, receivers, resultTo, resultCode,
16335                    resultData, map, ordered, sticky, false, userId);
16336            if (DEBUG_BROADCAST) Slog.v(
16337                    TAG, "Enqueueing ordered broadcast " + r
16338                    + ": prev had " + queue.mOrderedBroadcasts.size());
16339            if (DEBUG_BROADCAST) {
16340                int seq = r.intent.getIntExtra("seq", -1);
16341                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16342            }
16343            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16344            if (!replaced) {
16345                queue.enqueueOrderedBroadcastLocked(r);
16346                queue.scheduleBroadcastsLocked();
16347            }
16348        }
16349
16350        return ActivityManager.BROADCAST_SUCCESS;
16351    }
16352
16353    final Intent verifyBroadcastLocked(Intent intent) {
16354        // Refuse possible leaked file descriptors
16355        if (intent != null && intent.hasFileDescriptors() == true) {
16356            throw new IllegalArgumentException("File descriptors passed in Intent");
16357        }
16358
16359        int flags = intent.getFlags();
16360
16361        if (!mProcessesReady) {
16362            // if the caller really truly claims to know what they're doing, go
16363            // ahead and allow the broadcast without launching any receivers
16364            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16365                intent = new Intent(intent);
16366                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16367            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16368                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16369                        + " before boot completion");
16370                throw new IllegalStateException("Cannot broadcast before boot completed");
16371            }
16372        }
16373
16374        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16375            throw new IllegalArgumentException(
16376                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16377        }
16378
16379        return intent;
16380    }
16381
16382    public final int broadcastIntent(IApplicationThread caller,
16383            Intent intent, String resolvedType, IIntentReceiver resultTo,
16384            int resultCode, String resultData, Bundle map,
16385            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16386        enforceNotIsolatedCaller("broadcastIntent");
16387        synchronized(this) {
16388            intent = verifyBroadcastLocked(intent);
16389
16390            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16391            final int callingPid = Binder.getCallingPid();
16392            final int callingUid = Binder.getCallingUid();
16393            final long origId = Binder.clearCallingIdentity();
16394            int res = broadcastIntentLocked(callerApp,
16395                    callerApp != null ? callerApp.info.packageName : null,
16396                    intent, resolvedType, resultTo,
16397                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16398                    callingPid, callingUid, userId);
16399            Binder.restoreCallingIdentity(origId);
16400            return res;
16401        }
16402    }
16403
16404    int broadcastIntentInPackage(String packageName, int uid,
16405            Intent intent, String resolvedType, IIntentReceiver resultTo,
16406            int resultCode, String resultData, Bundle map,
16407            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16408        synchronized(this) {
16409            intent = verifyBroadcastLocked(intent);
16410
16411            final long origId = Binder.clearCallingIdentity();
16412            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16413                    resultTo, resultCode, resultData, map, requiredPermission,
16414                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16415            Binder.restoreCallingIdentity(origId);
16416            return res;
16417        }
16418    }
16419
16420    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16421        // Refuse possible leaked file descriptors
16422        if (intent != null && intent.hasFileDescriptors() == true) {
16423            throw new IllegalArgumentException("File descriptors passed in Intent");
16424        }
16425
16426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16427                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16428
16429        synchronized(this) {
16430            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16431                    != PackageManager.PERMISSION_GRANTED) {
16432                String msg = "Permission Denial: unbroadcastIntent() from pid="
16433                        + Binder.getCallingPid()
16434                        + ", uid=" + Binder.getCallingUid()
16435                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16436                Slog.w(TAG, msg);
16437                throw new SecurityException(msg);
16438            }
16439            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16440            if (stickies != null) {
16441                ArrayList<Intent> list = stickies.get(intent.getAction());
16442                if (list != null) {
16443                    int N = list.size();
16444                    int i;
16445                    for (i=0; i<N; i++) {
16446                        if (intent.filterEquals(list.get(i))) {
16447                            list.remove(i);
16448                            break;
16449                        }
16450                    }
16451                    if (list.size() <= 0) {
16452                        stickies.remove(intent.getAction());
16453                    }
16454                }
16455                if (stickies.size() <= 0) {
16456                    mStickyBroadcasts.remove(userId);
16457                }
16458            }
16459        }
16460    }
16461
16462    void backgroundServicesFinishedLocked(int userId) {
16463        for (BroadcastQueue queue : mBroadcastQueues) {
16464            queue.backgroundServicesFinishedLocked(userId);
16465        }
16466    }
16467
16468    public void finishReceiver(IBinder who, int resultCode, String resultData,
16469            Bundle resultExtras, boolean resultAbort, int flags) {
16470        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16471
16472        // Refuse possible leaked file descriptors
16473        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16474            throw new IllegalArgumentException("File descriptors passed in Bundle");
16475        }
16476
16477        final long origId = Binder.clearCallingIdentity();
16478        try {
16479            boolean doNext = false;
16480            BroadcastRecord r;
16481
16482            synchronized(this) {
16483                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16484                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16485                r = queue.getMatchingOrderedReceiver(who);
16486                if (r != null) {
16487                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16488                        resultData, resultExtras, resultAbort, true);
16489                }
16490            }
16491
16492            if (doNext) {
16493                r.queue.processNextBroadcast(false);
16494            }
16495            trimApplications();
16496        } finally {
16497            Binder.restoreCallingIdentity(origId);
16498        }
16499    }
16500
16501    // =========================================================
16502    // INSTRUMENTATION
16503    // =========================================================
16504
16505    public boolean startInstrumentation(ComponentName className,
16506            String profileFile, int flags, Bundle arguments,
16507            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16508            int userId, String abiOverride) {
16509        enforceNotIsolatedCaller("startInstrumentation");
16510        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16511                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16512        // Refuse possible leaked file descriptors
16513        if (arguments != null && arguments.hasFileDescriptors()) {
16514            throw new IllegalArgumentException("File descriptors passed in Bundle");
16515        }
16516
16517        synchronized(this) {
16518            InstrumentationInfo ii = null;
16519            ApplicationInfo ai = null;
16520            try {
16521                ii = mContext.getPackageManager().getInstrumentationInfo(
16522                    className, STOCK_PM_FLAGS);
16523                ai = AppGlobals.getPackageManager().getApplicationInfo(
16524                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16525            } catch (PackageManager.NameNotFoundException e) {
16526            } catch (RemoteException e) {
16527            }
16528            if (ii == null) {
16529                reportStartInstrumentationFailure(watcher, className,
16530                        "Unable to find instrumentation info for: " + className);
16531                return false;
16532            }
16533            if (ai == null) {
16534                reportStartInstrumentationFailure(watcher, className,
16535                        "Unable to find instrumentation target package: " + ii.targetPackage);
16536                return false;
16537            }
16538
16539            int match = mContext.getPackageManager().checkSignatures(
16540                    ii.targetPackage, ii.packageName);
16541            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16542                String msg = "Permission Denial: starting instrumentation "
16543                        + className + " from pid="
16544                        + Binder.getCallingPid()
16545                        + ", uid=" + Binder.getCallingPid()
16546                        + " not allowed because package " + ii.packageName
16547                        + " does not have a signature matching the target "
16548                        + ii.targetPackage;
16549                reportStartInstrumentationFailure(watcher, className, msg);
16550                throw new SecurityException(msg);
16551            }
16552
16553            final long origId = Binder.clearCallingIdentity();
16554            // Instrumentation can kill and relaunch even persistent processes
16555            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16556                    "start instr");
16557            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16558            app.instrumentationClass = className;
16559            app.instrumentationInfo = ai;
16560            app.instrumentationProfileFile = profileFile;
16561            app.instrumentationArguments = arguments;
16562            app.instrumentationWatcher = watcher;
16563            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16564            app.instrumentationResultClass = className;
16565            Binder.restoreCallingIdentity(origId);
16566        }
16567
16568        return true;
16569    }
16570
16571    /**
16572     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16573     * error to the logs, but if somebody is watching, send the report there too.  This enables
16574     * the "am" command to report errors with more information.
16575     *
16576     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16577     * @param cn The component name of the instrumentation.
16578     * @param report The error report.
16579     */
16580    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16581            ComponentName cn, String report) {
16582        Slog.w(TAG, report);
16583        try {
16584            if (watcher != null) {
16585                Bundle results = new Bundle();
16586                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16587                results.putString("Error", report);
16588                watcher.instrumentationStatus(cn, -1, results);
16589            }
16590        } catch (RemoteException e) {
16591            Slog.w(TAG, e);
16592        }
16593    }
16594
16595    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16596        if (app.instrumentationWatcher != null) {
16597            try {
16598                // NOTE:  IInstrumentationWatcher *must* be oneway here
16599                app.instrumentationWatcher.instrumentationFinished(
16600                    app.instrumentationClass,
16601                    resultCode,
16602                    results);
16603            } catch (RemoteException e) {
16604            }
16605        }
16606        if (app.instrumentationUiAutomationConnection != null) {
16607            try {
16608                app.instrumentationUiAutomationConnection.shutdown();
16609            } catch (RemoteException re) {
16610                /* ignore */
16611            }
16612            // Only a UiAutomation can set this flag and now that
16613            // it is finished we make sure it is reset to its default.
16614            mUserIsMonkey = false;
16615        }
16616        app.instrumentationWatcher = null;
16617        app.instrumentationUiAutomationConnection = null;
16618        app.instrumentationClass = null;
16619        app.instrumentationInfo = null;
16620        app.instrumentationProfileFile = null;
16621        app.instrumentationArguments = null;
16622
16623        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16624                "finished inst");
16625    }
16626
16627    public void finishInstrumentation(IApplicationThread target,
16628            int resultCode, Bundle results) {
16629        int userId = UserHandle.getCallingUserId();
16630        // Refuse possible leaked file descriptors
16631        if (results != null && results.hasFileDescriptors()) {
16632            throw new IllegalArgumentException("File descriptors passed in Intent");
16633        }
16634
16635        synchronized(this) {
16636            ProcessRecord app = getRecordForAppLocked(target);
16637            if (app == null) {
16638                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16639                return;
16640            }
16641            final long origId = Binder.clearCallingIdentity();
16642            finishInstrumentationLocked(app, resultCode, results);
16643            Binder.restoreCallingIdentity(origId);
16644        }
16645    }
16646
16647    // =========================================================
16648    // CONFIGURATION
16649    // =========================================================
16650
16651    public ConfigurationInfo getDeviceConfigurationInfo() {
16652        ConfigurationInfo config = new ConfigurationInfo();
16653        synchronized (this) {
16654            config.reqTouchScreen = mConfiguration.touchscreen;
16655            config.reqKeyboardType = mConfiguration.keyboard;
16656            config.reqNavigation = mConfiguration.navigation;
16657            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16658                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16659                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16660            }
16661            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16662                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16663                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16664            }
16665            config.reqGlEsVersion = GL_ES_VERSION;
16666        }
16667        return config;
16668    }
16669
16670    ActivityStack getFocusedStack() {
16671        return mStackSupervisor.getFocusedStack();
16672    }
16673
16674    public Configuration getConfiguration() {
16675        Configuration ci;
16676        synchronized(this) {
16677            ci = new Configuration(mConfiguration);
16678            ci.userSetLocale = false;
16679        }
16680        return ci;
16681    }
16682
16683    public void updatePersistentConfiguration(Configuration values) {
16684        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16685                "updateConfiguration()");
16686        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16687                "updateConfiguration()");
16688        if (values == null) {
16689            throw new NullPointerException("Configuration must not be null");
16690        }
16691
16692        synchronized(this) {
16693            final long origId = Binder.clearCallingIdentity();
16694            updateConfigurationLocked(values, null, true, false);
16695            Binder.restoreCallingIdentity(origId);
16696        }
16697    }
16698
16699    public void updateConfiguration(Configuration values) {
16700        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16701                "updateConfiguration()");
16702
16703        synchronized(this) {
16704            if (values == null && mWindowManager != null) {
16705                // sentinel: fetch the current configuration from the window manager
16706                values = mWindowManager.computeNewConfiguration();
16707            }
16708
16709            if (mWindowManager != null) {
16710                mProcessList.applyDisplaySize(mWindowManager);
16711            }
16712
16713            final long origId = Binder.clearCallingIdentity();
16714            if (values != null) {
16715                Settings.System.clearConfiguration(values);
16716            }
16717            updateConfigurationLocked(values, null, false, false);
16718            Binder.restoreCallingIdentity(origId);
16719        }
16720    }
16721
16722    /**
16723     * Do either or both things: (1) change the current configuration, and (2)
16724     * make sure the given activity is running with the (now) current
16725     * configuration.  Returns true if the activity has been left running, or
16726     * false if <var>starting</var> is being destroyed to match the new
16727     * configuration.
16728     * @param persistent TODO
16729     */
16730    boolean updateConfigurationLocked(Configuration values,
16731            ActivityRecord starting, boolean persistent, boolean initLocale) {
16732        int changes = 0;
16733
16734        if (values != null) {
16735            Configuration newConfig = new Configuration(mConfiguration);
16736            changes = newConfig.updateFrom(values);
16737            if (changes != 0) {
16738                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16739                    Slog.i(TAG, "Updating configuration to: " + values);
16740                }
16741
16742                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16743
16744                if (!initLocale && values.locale != null && values.userSetLocale) {
16745                    final String languageTag = values.locale.toLanguageTag();
16746                    SystemProperties.set("persist.sys.locale", languageTag);
16747                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16748                            values.locale));
16749                }
16750
16751                mConfigurationSeq++;
16752                if (mConfigurationSeq <= 0) {
16753                    mConfigurationSeq = 1;
16754                }
16755                newConfig.seq = mConfigurationSeq;
16756                mConfiguration = newConfig;
16757                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16758                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16759                //mUsageStatsService.noteStartConfig(newConfig);
16760
16761                final Configuration configCopy = new Configuration(mConfiguration);
16762
16763                // TODO: If our config changes, should we auto dismiss any currently
16764                // showing dialogs?
16765                mShowDialogs = shouldShowDialogs(newConfig);
16766
16767                AttributeCache ac = AttributeCache.instance();
16768                if (ac != null) {
16769                    ac.updateConfiguration(configCopy);
16770                }
16771
16772                // Make sure all resources in our process are updated
16773                // right now, so that anyone who is going to retrieve
16774                // resource values after we return will be sure to get
16775                // the new ones.  This is especially important during
16776                // boot, where the first config change needs to guarantee
16777                // all resources have that config before following boot
16778                // code is executed.
16779                mSystemThread.applyConfigurationToResources(configCopy);
16780
16781                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16782                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16783                    msg.obj = new Configuration(configCopy);
16784                    mHandler.sendMessage(msg);
16785                }
16786
16787                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16788                    ProcessRecord app = mLruProcesses.get(i);
16789                    try {
16790                        if (app.thread != null) {
16791                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16792                                    + app.processName + " new config " + mConfiguration);
16793                            app.thread.scheduleConfigurationChanged(configCopy);
16794                        }
16795                    } catch (Exception e) {
16796                    }
16797                }
16798                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16799                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16800                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16801                        | Intent.FLAG_RECEIVER_FOREGROUND);
16802                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16803                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16804                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16805                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16806                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16807                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16808                    broadcastIntentLocked(null, null, intent,
16809                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16810                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16811                }
16812            }
16813        }
16814
16815        boolean kept = true;
16816        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16817        // mainStack is null during startup.
16818        if (mainStack != null) {
16819            if (changes != 0 && starting == null) {
16820                // If the configuration changed, and the caller is not already
16821                // in the process of starting an activity, then find the top
16822                // activity to check if its configuration needs to change.
16823                starting = mainStack.topRunningActivityLocked(null);
16824            }
16825
16826            if (starting != null) {
16827                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16828                // And we need to make sure at this point that all other activities
16829                // are made visible with the correct configuration.
16830                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16831            }
16832        }
16833
16834        if (values != null && mWindowManager != null) {
16835            mWindowManager.setNewConfiguration(mConfiguration);
16836        }
16837
16838        return kept;
16839    }
16840
16841    /**
16842     * Decide based on the configuration whether we should shouw the ANR,
16843     * crash, etc dialogs.  The idea is that if there is no affordnace to
16844     * press the on-screen buttons, we shouldn't show the dialog.
16845     *
16846     * A thought: SystemUI might also want to get told about this, the Power
16847     * dialog / global actions also might want different behaviors.
16848     */
16849    private static final boolean shouldShowDialogs(Configuration config) {
16850        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16851                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16852    }
16853
16854    @Override
16855    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16856        synchronized (this) {
16857            ActivityRecord srec = ActivityRecord.forToken(token);
16858            if (srec.task != null && srec.task.stack != null) {
16859                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16860            }
16861        }
16862        return false;
16863    }
16864
16865    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16866            Intent resultData) {
16867
16868        synchronized (this) {
16869            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16870            if (stack != null) {
16871                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16872            }
16873            return false;
16874        }
16875    }
16876
16877    public int getLaunchedFromUid(IBinder activityToken) {
16878        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16879        if (srec == null) {
16880            return -1;
16881        }
16882        return srec.launchedFromUid;
16883    }
16884
16885    public String getLaunchedFromPackage(IBinder activityToken) {
16886        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16887        if (srec == null) {
16888            return null;
16889        }
16890        return srec.launchedFromPackage;
16891    }
16892
16893    // =========================================================
16894    // LIFETIME MANAGEMENT
16895    // =========================================================
16896
16897    // Returns which broadcast queue the app is the current [or imminent] receiver
16898    // on, or 'null' if the app is not an active broadcast recipient.
16899    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16900        BroadcastRecord r = app.curReceiver;
16901        if (r != null) {
16902            return r.queue;
16903        }
16904
16905        // It's not the current receiver, but it might be starting up to become one
16906        synchronized (this) {
16907            for (BroadcastQueue queue : mBroadcastQueues) {
16908                r = queue.mPendingBroadcast;
16909                if (r != null && r.curApp == app) {
16910                    // found it; report which queue it's in
16911                    return queue;
16912                }
16913            }
16914        }
16915
16916        return null;
16917    }
16918
16919    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16920            ComponentName targetComponent, String targetProcess) {
16921        if (!mTrackingAssociations) {
16922            return null;
16923        }
16924        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16925                = mAssociations.get(targetUid);
16926        if (components == null) {
16927            components = new ArrayMap<>();
16928            mAssociations.put(targetUid, components);
16929        }
16930        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16931        if (sourceUids == null) {
16932            sourceUids = new SparseArray<>();
16933            components.put(targetComponent, sourceUids);
16934        }
16935        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16936        if (sourceProcesses == null) {
16937            sourceProcesses = new ArrayMap<>();
16938            sourceUids.put(sourceUid, sourceProcesses);
16939        }
16940        Association ass = sourceProcesses.get(sourceProcess);
16941        if (ass == null) {
16942            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16943                    targetProcess);
16944            sourceProcesses.put(sourceProcess, ass);
16945        }
16946        ass.mCount++;
16947        ass.mNesting++;
16948        if (ass.mNesting == 1) {
16949            ass.mStartTime = SystemClock.uptimeMillis();
16950        }
16951        return ass;
16952    }
16953
16954    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16955            ComponentName targetComponent) {
16956        if (!mTrackingAssociations) {
16957            return;
16958        }
16959        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16960                = mAssociations.get(targetUid);
16961        if (components == null) {
16962            return;
16963        }
16964        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16965        if (sourceUids == null) {
16966            return;
16967        }
16968        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16969        if (sourceProcesses == null) {
16970            return;
16971        }
16972        Association ass = sourceProcesses.get(sourceProcess);
16973        if (ass == null || ass.mNesting <= 0) {
16974            return;
16975        }
16976        ass.mNesting--;
16977        if (ass.mNesting == 0) {
16978            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16979        }
16980    }
16981
16982    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16983            boolean doingAll, long now) {
16984        if (mAdjSeq == app.adjSeq) {
16985            // This adjustment has already been computed.
16986            return app.curRawAdj;
16987        }
16988
16989        if (app.thread == null) {
16990            app.adjSeq = mAdjSeq;
16991            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16992            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16993            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16994        }
16995
16996        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16997        app.adjSource = null;
16998        app.adjTarget = null;
16999        app.empty = false;
17000        app.cached = false;
17001
17002        final int activitiesSize = app.activities.size();
17003
17004        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17005            // The max adjustment doesn't allow this app to be anything
17006            // below foreground, so it is not worth doing work for it.
17007            app.adjType = "fixed";
17008            app.adjSeq = mAdjSeq;
17009            app.curRawAdj = app.maxAdj;
17010            app.foregroundActivities = false;
17011            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17012            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17013            // System processes can do UI, and when they do we want to have
17014            // them trim their memory after the user leaves the UI.  To
17015            // facilitate this, here we need to determine whether or not it
17016            // is currently showing UI.
17017            app.systemNoUi = true;
17018            if (app == TOP_APP) {
17019                app.systemNoUi = false;
17020            } else if (activitiesSize > 0) {
17021                for (int j = 0; j < activitiesSize; j++) {
17022                    final ActivityRecord r = app.activities.get(j);
17023                    if (r.visible) {
17024                        app.systemNoUi = false;
17025                    }
17026                }
17027            }
17028            if (!app.systemNoUi) {
17029                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17030            }
17031            return (app.curAdj=app.maxAdj);
17032        }
17033
17034        app.systemNoUi = false;
17035
17036        // Determine the importance of the process, starting with most
17037        // important to least, and assign an appropriate OOM adjustment.
17038        int adj;
17039        int schedGroup;
17040        int procState;
17041        boolean foregroundActivities = false;
17042        BroadcastQueue queue;
17043        if (app == TOP_APP) {
17044            // The last app on the list is the foreground app.
17045            adj = ProcessList.FOREGROUND_APP_ADJ;
17046            schedGroup = Process.THREAD_GROUP_DEFAULT;
17047            app.adjType = "top-activity";
17048            foregroundActivities = true;
17049            procState = ActivityManager.PROCESS_STATE_TOP;
17050        } else if (app.instrumentationClass != null) {
17051            // Don't want to kill running instrumentation.
17052            adj = ProcessList.FOREGROUND_APP_ADJ;
17053            schedGroup = Process.THREAD_GROUP_DEFAULT;
17054            app.adjType = "instrumentation";
17055            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17056        } else if ((queue = isReceivingBroadcast(app)) != null) {
17057            // An app that is currently receiving a broadcast also
17058            // counts as being in the foreground for OOM killer purposes.
17059            // It's placed in a sched group based on the nature of the
17060            // broadcast as reflected by which queue it's active in.
17061            adj = ProcessList.FOREGROUND_APP_ADJ;
17062            schedGroup = (queue == mFgBroadcastQueue)
17063                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17064            app.adjType = "broadcast";
17065            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17066        } else if (app.executingServices.size() > 0) {
17067            // An app that is currently executing a service callback also
17068            // counts as being in the foreground.
17069            adj = ProcessList.FOREGROUND_APP_ADJ;
17070            schedGroup = app.execServicesFg ?
17071                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17072            app.adjType = "exec-service";
17073            procState = ActivityManager.PROCESS_STATE_SERVICE;
17074            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17075        } else {
17076            // As far as we know the process is empty.  We may change our mind later.
17077            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17078            // At this point we don't actually know the adjustment.  Use the cached adj
17079            // value that the caller wants us to.
17080            adj = cachedAdj;
17081            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17082            app.cached = true;
17083            app.empty = true;
17084            app.adjType = "cch-empty";
17085        }
17086
17087        // Examine all activities if not already foreground.
17088        if (!foregroundActivities && activitiesSize > 0) {
17089            for (int j = 0; j < activitiesSize; j++) {
17090                final ActivityRecord r = app.activities.get(j);
17091                if (r.app != app) {
17092                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17093                            + app + "?!?");
17094                    continue;
17095                }
17096                if (r.visible) {
17097                    // App has a visible activity; only upgrade adjustment.
17098                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17099                        adj = ProcessList.VISIBLE_APP_ADJ;
17100                        app.adjType = "visible";
17101                    }
17102                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17103                        procState = ActivityManager.PROCESS_STATE_TOP;
17104                    }
17105                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17106                    app.cached = false;
17107                    app.empty = false;
17108                    foregroundActivities = true;
17109                    break;
17110                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17111                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17112                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17113                        app.adjType = "pausing";
17114                    }
17115                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17116                        procState = ActivityManager.PROCESS_STATE_TOP;
17117                    }
17118                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17119                    app.cached = false;
17120                    app.empty = false;
17121                    foregroundActivities = true;
17122                } else if (r.state == ActivityState.STOPPING) {
17123                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17124                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17125                        app.adjType = "stopping";
17126                    }
17127                    // For the process state, we will at this point consider the
17128                    // process to be cached.  It will be cached either as an activity
17129                    // or empty depending on whether the activity is finishing.  We do
17130                    // this so that we can treat the process as cached for purposes of
17131                    // memory trimming (determing current memory level, trim command to
17132                    // send to process) since there can be an arbitrary number of stopping
17133                    // processes and they should soon all go into the cached state.
17134                    if (!r.finishing) {
17135                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17136                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17137                        }
17138                    }
17139                    app.cached = false;
17140                    app.empty = false;
17141                    foregroundActivities = true;
17142                } else {
17143                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17144                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17145                        app.adjType = "cch-act";
17146                    }
17147                }
17148            }
17149        }
17150
17151        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17152            if (app.foregroundServices) {
17153                // The user is aware of this app, so make it visible.
17154                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17155                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17156                app.cached = false;
17157                app.adjType = "fg-service";
17158                schedGroup = Process.THREAD_GROUP_DEFAULT;
17159            } else if (app.forcingToForeground != null) {
17160                // The user is aware of this app, so make it visible.
17161                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17162                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17163                app.cached = false;
17164                app.adjType = "force-fg";
17165                app.adjSource = app.forcingToForeground;
17166                schedGroup = Process.THREAD_GROUP_DEFAULT;
17167            }
17168        }
17169
17170        if (app == mHeavyWeightProcess) {
17171            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17172                // We don't want to kill the current heavy-weight process.
17173                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17174                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17175                app.cached = false;
17176                app.adjType = "heavy";
17177            }
17178            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17179                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17180            }
17181        }
17182
17183        if (app == mHomeProcess) {
17184            if (adj > ProcessList.HOME_APP_ADJ) {
17185                // This process is hosting what we currently consider to be the
17186                // home app, so we don't want to let it go into the background.
17187                adj = ProcessList.HOME_APP_ADJ;
17188                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17189                app.cached = false;
17190                app.adjType = "home";
17191            }
17192            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17193                procState = ActivityManager.PROCESS_STATE_HOME;
17194            }
17195        }
17196
17197        if (app == mPreviousProcess && app.activities.size() > 0) {
17198            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17199                // This was the previous process that showed UI to the user.
17200                // We want to try to keep it around more aggressively, to give
17201                // a good experience around switching between two apps.
17202                adj = ProcessList.PREVIOUS_APP_ADJ;
17203                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17204                app.cached = false;
17205                app.adjType = "previous";
17206            }
17207            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17208                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17209            }
17210        }
17211
17212        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17213                + " reason=" + app.adjType);
17214
17215        // By default, we use the computed adjustment.  It may be changed if
17216        // there are applications dependent on our services or providers, but
17217        // this gives us a baseline and makes sure we don't get into an
17218        // infinite recursion.
17219        app.adjSeq = mAdjSeq;
17220        app.curRawAdj = adj;
17221        app.hasStartedServices = false;
17222
17223        if (mBackupTarget != null && app == mBackupTarget.app) {
17224            // If possible we want to avoid killing apps while they're being backed up
17225            if (adj > ProcessList.BACKUP_APP_ADJ) {
17226                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17227                adj = ProcessList.BACKUP_APP_ADJ;
17228                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17229                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17230                }
17231                app.adjType = "backup";
17232                app.cached = false;
17233            }
17234            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17235                procState = ActivityManager.PROCESS_STATE_BACKUP;
17236            }
17237        }
17238
17239        boolean mayBeTop = false;
17240
17241        for (int is = app.services.size()-1;
17242                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17243                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17244                        || procState > ActivityManager.PROCESS_STATE_TOP);
17245                is--) {
17246            ServiceRecord s = app.services.valueAt(is);
17247            if (s.startRequested) {
17248                app.hasStartedServices = true;
17249                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17250                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17251                }
17252                if (app.hasShownUi && app != mHomeProcess) {
17253                    // If this process has shown some UI, let it immediately
17254                    // go to the LRU list because it may be pretty heavy with
17255                    // UI stuff.  We'll tag it with a label just to help
17256                    // debug and understand what is going on.
17257                    if (adj > ProcessList.SERVICE_ADJ) {
17258                        app.adjType = "cch-started-ui-services";
17259                    }
17260                } else {
17261                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17262                        // This service has seen some activity within
17263                        // recent memory, so we will keep its process ahead
17264                        // of the background processes.
17265                        if (adj > ProcessList.SERVICE_ADJ) {
17266                            adj = ProcessList.SERVICE_ADJ;
17267                            app.adjType = "started-services";
17268                            app.cached = false;
17269                        }
17270                    }
17271                    // If we have let the service slide into the background
17272                    // state, still have some text describing what it is doing
17273                    // even though the service no longer has an impact.
17274                    if (adj > ProcessList.SERVICE_ADJ) {
17275                        app.adjType = "cch-started-services";
17276                    }
17277                }
17278            }
17279            for (int conni = s.connections.size()-1;
17280                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17281                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17282                            || procState > ActivityManager.PROCESS_STATE_TOP);
17283                    conni--) {
17284                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17285                for (int i = 0;
17286                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17287                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17288                                || procState > ActivityManager.PROCESS_STATE_TOP);
17289                        i++) {
17290                    // XXX should compute this based on the max of
17291                    // all connected clients.
17292                    ConnectionRecord cr = clist.get(i);
17293                    if (cr.binding.client == app) {
17294                        // Binding to ourself is not interesting.
17295                        continue;
17296                    }
17297                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17298                        ProcessRecord client = cr.binding.client;
17299                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17300                                TOP_APP, doingAll, now);
17301                        int clientProcState = client.curProcState;
17302                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17303                            // If the other app is cached for any reason, for purposes here
17304                            // we are going to consider it empty.  The specific cached state
17305                            // doesn't propagate except under certain conditions.
17306                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17307                        }
17308                        String adjType = null;
17309                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17310                            // Not doing bind OOM management, so treat
17311                            // this guy more like a started service.
17312                            if (app.hasShownUi && app != mHomeProcess) {
17313                                // If this process has shown some UI, let it immediately
17314                                // go to the LRU list because it may be pretty heavy with
17315                                // UI stuff.  We'll tag it with a label just to help
17316                                // debug and understand what is going on.
17317                                if (adj > clientAdj) {
17318                                    adjType = "cch-bound-ui-services";
17319                                }
17320                                app.cached = false;
17321                                clientAdj = adj;
17322                                clientProcState = procState;
17323                            } else {
17324                                if (now >= (s.lastActivity
17325                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17326                                    // This service has not seen activity within
17327                                    // recent memory, so allow it to drop to the
17328                                    // LRU list if there is no other reason to keep
17329                                    // it around.  We'll also tag it with a label just
17330                                    // to help debug and undertand what is going on.
17331                                    if (adj > clientAdj) {
17332                                        adjType = "cch-bound-services";
17333                                    }
17334                                    clientAdj = adj;
17335                                }
17336                            }
17337                        }
17338                        if (adj > clientAdj) {
17339                            // If this process has recently shown UI, and
17340                            // the process that is binding to it is less
17341                            // important than being visible, then we don't
17342                            // care about the binding as much as we care
17343                            // about letting this process get into the LRU
17344                            // list to be killed and restarted if needed for
17345                            // memory.
17346                            if (app.hasShownUi && app != mHomeProcess
17347                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17348                                adjType = "cch-bound-ui-services";
17349                            } else {
17350                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17351                                        |Context.BIND_IMPORTANT)) != 0) {
17352                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17353                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17354                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17355                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17356                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17357                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17358                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17359                                    adj = clientAdj;
17360                                } else {
17361                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17362                                        adj = ProcessList.VISIBLE_APP_ADJ;
17363                                    }
17364                                }
17365                                if (!client.cached) {
17366                                    app.cached = false;
17367                                }
17368                                adjType = "service";
17369                            }
17370                        }
17371                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17372                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17373                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17374                            }
17375                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17376                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17377                                    // Special handling of clients who are in the top state.
17378                                    // We *may* want to consider this process to be in the
17379                                    // top state as well, but only if there is not another
17380                                    // reason for it to be running.  Being on the top is a
17381                                    // special state, meaning you are specifically running
17382                                    // for the current top app.  If the process is already
17383                                    // running in the background for some other reason, it
17384                                    // is more important to continue considering it to be
17385                                    // in the background state.
17386                                    mayBeTop = true;
17387                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17388                                } else {
17389                                    // Special handling for above-top states (persistent
17390                                    // processes).  These should not bring the current process
17391                                    // into the top state, since they are not on top.  Instead
17392                                    // give them the best state after that.
17393                                    clientProcState =
17394                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17395                                }
17396                            }
17397                        } else {
17398                            if (clientProcState <
17399                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17400                                clientProcState =
17401                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17402                            }
17403                        }
17404                        if (procState > clientProcState) {
17405                            procState = clientProcState;
17406                        }
17407                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17408                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17409                            app.pendingUiClean = true;
17410                        }
17411                        if (adjType != null) {
17412                            app.adjType = adjType;
17413                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17414                                    .REASON_SERVICE_IN_USE;
17415                            app.adjSource = cr.binding.client;
17416                            app.adjSourceProcState = clientProcState;
17417                            app.adjTarget = s.name;
17418                        }
17419                    }
17420                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17421                        app.treatLikeActivity = true;
17422                    }
17423                    final ActivityRecord a = cr.activity;
17424                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17425                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17426                                (a.visible || a.state == ActivityState.RESUMED
17427                                 || a.state == ActivityState.PAUSING)) {
17428                            adj = ProcessList.FOREGROUND_APP_ADJ;
17429                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17430                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17431                            }
17432                            app.cached = false;
17433                            app.adjType = "service";
17434                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17435                                    .REASON_SERVICE_IN_USE;
17436                            app.adjSource = a;
17437                            app.adjSourceProcState = procState;
17438                            app.adjTarget = s.name;
17439                        }
17440                    }
17441                }
17442            }
17443        }
17444
17445        for (int provi = app.pubProviders.size()-1;
17446                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17447                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17448                        || procState > ActivityManager.PROCESS_STATE_TOP);
17449                provi--) {
17450            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17451            for (int i = cpr.connections.size()-1;
17452                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17453                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17454                            || procState > ActivityManager.PROCESS_STATE_TOP);
17455                    i--) {
17456                ContentProviderConnection conn = cpr.connections.get(i);
17457                ProcessRecord client = conn.client;
17458                if (client == app) {
17459                    // Being our own client is not interesting.
17460                    continue;
17461                }
17462                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17463                int clientProcState = client.curProcState;
17464                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17465                    // If the other app is cached for any reason, for purposes here
17466                    // we are going to consider it empty.
17467                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17468                }
17469                if (adj > clientAdj) {
17470                    if (app.hasShownUi && app != mHomeProcess
17471                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17472                        app.adjType = "cch-ui-provider";
17473                    } else {
17474                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17475                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17476                        app.adjType = "provider";
17477                    }
17478                    app.cached &= client.cached;
17479                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17480                            .REASON_PROVIDER_IN_USE;
17481                    app.adjSource = client;
17482                    app.adjSourceProcState = clientProcState;
17483                    app.adjTarget = cpr.name;
17484                }
17485                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17486                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17487                        // Special handling of clients who are in the top state.
17488                        // We *may* want to consider this process to be in the
17489                        // top state as well, but only if there is not another
17490                        // reason for it to be running.  Being on the top is a
17491                        // special state, meaning you are specifically running
17492                        // for the current top app.  If the process is already
17493                        // running in the background for some other reason, it
17494                        // is more important to continue considering it to be
17495                        // in the background state.
17496                        mayBeTop = true;
17497                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17498                    } else {
17499                        // Special handling for above-top states (persistent
17500                        // processes).  These should not bring the current process
17501                        // into the top state, since they are not on top.  Instead
17502                        // give them the best state after that.
17503                        clientProcState =
17504                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17505                    }
17506                }
17507                if (procState > clientProcState) {
17508                    procState = clientProcState;
17509                }
17510                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17511                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17512                }
17513            }
17514            // If the provider has external (non-framework) process
17515            // dependencies, ensure that its adjustment is at least
17516            // FOREGROUND_APP_ADJ.
17517            if (cpr.hasExternalProcessHandles()) {
17518                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17519                    adj = ProcessList.FOREGROUND_APP_ADJ;
17520                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17521                    app.cached = false;
17522                    app.adjType = "provider";
17523                    app.adjTarget = cpr.name;
17524                }
17525                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17526                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17527                }
17528            }
17529        }
17530
17531        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17532            // A client of one of our services or providers is in the top state.  We
17533            // *may* want to be in the top state, but not if we are already running in
17534            // the background for some other reason.  For the decision here, we are going
17535            // to pick out a few specific states that we want to remain in when a client
17536            // is top (states that tend to be longer-term) and otherwise allow it to go
17537            // to the top state.
17538            switch (procState) {
17539                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17540                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17541                case ActivityManager.PROCESS_STATE_SERVICE:
17542                    // These all are longer-term states, so pull them up to the top
17543                    // of the background states, but not all the way to the top state.
17544                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17545                    break;
17546                default:
17547                    // Otherwise, top is a better choice, so take it.
17548                    procState = ActivityManager.PROCESS_STATE_TOP;
17549                    break;
17550            }
17551        }
17552
17553        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17554            if (app.hasClientActivities) {
17555                // This is a cached process, but with client activities.  Mark it so.
17556                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17557                app.adjType = "cch-client-act";
17558            } else if (app.treatLikeActivity) {
17559                // This is a cached process, but somebody wants us to treat it like it has
17560                // an activity, okay!
17561                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17562                app.adjType = "cch-as-act";
17563            }
17564        }
17565
17566        if (adj == ProcessList.SERVICE_ADJ) {
17567            if (doingAll) {
17568                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17569                mNewNumServiceProcs++;
17570                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17571                if (!app.serviceb) {
17572                    // This service isn't far enough down on the LRU list to
17573                    // normally be a B service, but if we are low on RAM and it
17574                    // is large we want to force it down since we would prefer to
17575                    // keep launcher over it.
17576                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17577                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17578                        app.serviceHighRam = true;
17579                        app.serviceb = true;
17580                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17581                    } else {
17582                        mNewNumAServiceProcs++;
17583                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17584                    }
17585                } else {
17586                    app.serviceHighRam = false;
17587                }
17588            }
17589            if (app.serviceb) {
17590                adj = ProcessList.SERVICE_B_ADJ;
17591            }
17592        }
17593
17594        app.curRawAdj = adj;
17595
17596        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17597        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17598        if (adj > app.maxAdj) {
17599            adj = app.maxAdj;
17600            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17601                schedGroup = Process.THREAD_GROUP_DEFAULT;
17602            }
17603        }
17604
17605        // Do final modification to adj.  Everything we do between here and applying
17606        // the final setAdj must be done in this function, because we will also use
17607        // it when computing the final cached adj later.  Note that we don't need to
17608        // worry about this for max adj above, since max adj will always be used to
17609        // keep it out of the cached vaues.
17610        app.curAdj = app.modifyRawOomAdj(adj);
17611        app.curSchedGroup = schedGroup;
17612        app.curProcState = procState;
17613        app.foregroundActivities = foregroundActivities;
17614
17615        return app.curRawAdj;
17616    }
17617
17618    /**
17619     * Record new PSS sample for a process.
17620     */
17621    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17622        proc.lastPssTime = now;
17623        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17624        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17625                + ": " + pss + " lastPss=" + proc.lastPss
17626                + " state=" + ProcessList.makeProcStateString(procState));
17627        if (proc.initialIdlePss == 0) {
17628            proc.initialIdlePss = pss;
17629        }
17630        proc.lastPss = pss;
17631        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17632            proc.lastCachedPss = pss;
17633        }
17634    }
17635
17636    /**
17637     * Schedule PSS collection of a process.
17638     */
17639    void requestPssLocked(ProcessRecord proc, int procState) {
17640        if (mPendingPssProcesses.contains(proc)) {
17641            return;
17642        }
17643        if (mPendingPssProcesses.size() == 0) {
17644            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17645        }
17646        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17647        proc.pssProcState = procState;
17648        mPendingPssProcesses.add(proc);
17649    }
17650
17651    /**
17652     * Schedule PSS collection of all processes.
17653     */
17654    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17655        if (!always) {
17656            if (now < (mLastFullPssTime +
17657                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17658                return;
17659            }
17660        }
17661        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17662        mLastFullPssTime = now;
17663        mFullPssPending = true;
17664        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17665        mPendingPssProcesses.clear();
17666        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17667            ProcessRecord app = mLruProcesses.get(i);
17668            if (app.thread == null
17669                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17670                continue;
17671            }
17672            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17673                app.pssProcState = app.setProcState;
17674                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17675                        mTestPssMode, isSleeping(), now);
17676                mPendingPssProcesses.add(app);
17677            }
17678        }
17679        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17680    }
17681
17682    public void setTestPssMode(boolean enabled) {
17683        synchronized (this) {
17684            mTestPssMode = enabled;
17685            if (enabled) {
17686                // Whenever we enable the mode, we want to take a snapshot all of current
17687                // process mem use.
17688                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17689            }
17690        }
17691    }
17692
17693    /**
17694     * Ask a given process to GC right now.
17695     */
17696    final void performAppGcLocked(ProcessRecord app) {
17697        try {
17698            app.lastRequestedGc = SystemClock.uptimeMillis();
17699            if (app.thread != null) {
17700                if (app.reportLowMemory) {
17701                    app.reportLowMemory = false;
17702                    app.thread.scheduleLowMemory();
17703                } else {
17704                    app.thread.processInBackground();
17705                }
17706            }
17707        } catch (Exception e) {
17708            // whatever.
17709        }
17710    }
17711
17712    /**
17713     * Returns true if things are idle enough to perform GCs.
17714     */
17715    private final boolean canGcNowLocked() {
17716        boolean processingBroadcasts = false;
17717        for (BroadcastQueue q : mBroadcastQueues) {
17718            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17719                processingBroadcasts = true;
17720            }
17721        }
17722        return !processingBroadcasts
17723                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17724    }
17725
17726    /**
17727     * Perform GCs on all processes that are waiting for it, but only
17728     * if things are idle.
17729     */
17730    final void performAppGcsLocked() {
17731        final int N = mProcessesToGc.size();
17732        if (N <= 0) {
17733            return;
17734        }
17735        if (canGcNowLocked()) {
17736            while (mProcessesToGc.size() > 0) {
17737                ProcessRecord proc = mProcessesToGc.remove(0);
17738                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17739                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17740                            <= SystemClock.uptimeMillis()) {
17741                        // To avoid spamming the system, we will GC processes one
17742                        // at a time, waiting a few seconds between each.
17743                        performAppGcLocked(proc);
17744                        scheduleAppGcsLocked();
17745                        return;
17746                    } else {
17747                        // It hasn't been long enough since we last GCed this
17748                        // process...  put it in the list to wait for its time.
17749                        addProcessToGcListLocked(proc);
17750                        break;
17751                    }
17752                }
17753            }
17754
17755            scheduleAppGcsLocked();
17756        }
17757    }
17758
17759    /**
17760     * If all looks good, perform GCs on all processes waiting for them.
17761     */
17762    final void performAppGcsIfAppropriateLocked() {
17763        if (canGcNowLocked()) {
17764            performAppGcsLocked();
17765            return;
17766        }
17767        // Still not idle, wait some more.
17768        scheduleAppGcsLocked();
17769    }
17770
17771    /**
17772     * Schedule the execution of all pending app GCs.
17773     */
17774    final void scheduleAppGcsLocked() {
17775        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17776
17777        if (mProcessesToGc.size() > 0) {
17778            // Schedule a GC for the time to the next process.
17779            ProcessRecord proc = mProcessesToGc.get(0);
17780            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17781
17782            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17783            long now = SystemClock.uptimeMillis();
17784            if (when < (now+GC_TIMEOUT)) {
17785                when = now + GC_TIMEOUT;
17786            }
17787            mHandler.sendMessageAtTime(msg, when);
17788        }
17789    }
17790
17791    /**
17792     * Add a process to the array of processes waiting to be GCed.  Keeps the
17793     * list in sorted order by the last GC time.  The process can't already be
17794     * on the list.
17795     */
17796    final void addProcessToGcListLocked(ProcessRecord proc) {
17797        boolean added = false;
17798        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17799            if (mProcessesToGc.get(i).lastRequestedGc <
17800                    proc.lastRequestedGc) {
17801                added = true;
17802                mProcessesToGc.add(i+1, proc);
17803                break;
17804            }
17805        }
17806        if (!added) {
17807            mProcessesToGc.add(0, proc);
17808        }
17809    }
17810
17811    /**
17812     * Set up to ask a process to GC itself.  This will either do it
17813     * immediately, or put it on the list of processes to gc the next
17814     * time things are idle.
17815     */
17816    final void scheduleAppGcLocked(ProcessRecord app) {
17817        long now = SystemClock.uptimeMillis();
17818        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17819            return;
17820        }
17821        if (!mProcessesToGc.contains(app)) {
17822            addProcessToGcListLocked(app);
17823            scheduleAppGcsLocked();
17824        }
17825    }
17826
17827    final void checkExcessivePowerUsageLocked(boolean doKills) {
17828        updateCpuStatsNow();
17829
17830        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17831        boolean doWakeKills = doKills;
17832        boolean doCpuKills = doKills;
17833        if (mLastPowerCheckRealtime == 0) {
17834            doWakeKills = false;
17835        }
17836        if (mLastPowerCheckUptime == 0) {
17837            doCpuKills = false;
17838        }
17839        if (stats.isScreenOn()) {
17840            doWakeKills = false;
17841        }
17842        final long curRealtime = SystemClock.elapsedRealtime();
17843        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17844        final long curUptime = SystemClock.uptimeMillis();
17845        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17846        mLastPowerCheckRealtime = curRealtime;
17847        mLastPowerCheckUptime = curUptime;
17848        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17849            doWakeKills = false;
17850        }
17851        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17852            doCpuKills = false;
17853        }
17854        int i = mLruProcesses.size();
17855        while (i > 0) {
17856            i--;
17857            ProcessRecord app = mLruProcesses.get(i);
17858            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17859                long wtime;
17860                synchronized (stats) {
17861                    wtime = stats.getProcessWakeTime(app.info.uid,
17862                            app.pid, curRealtime);
17863                }
17864                long wtimeUsed = wtime - app.lastWakeTime;
17865                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17866                if (DEBUG_POWER) {
17867                    StringBuilder sb = new StringBuilder(128);
17868                    sb.append("Wake for ");
17869                    app.toShortString(sb);
17870                    sb.append(": over ");
17871                    TimeUtils.formatDuration(realtimeSince, sb);
17872                    sb.append(" used ");
17873                    TimeUtils.formatDuration(wtimeUsed, sb);
17874                    sb.append(" (");
17875                    sb.append((wtimeUsed*100)/realtimeSince);
17876                    sb.append("%)");
17877                    Slog.i(TAG, sb.toString());
17878                    sb.setLength(0);
17879                    sb.append("CPU for ");
17880                    app.toShortString(sb);
17881                    sb.append(": over ");
17882                    TimeUtils.formatDuration(uptimeSince, sb);
17883                    sb.append(" used ");
17884                    TimeUtils.formatDuration(cputimeUsed, sb);
17885                    sb.append(" (");
17886                    sb.append((cputimeUsed*100)/uptimeSince);
17887                    sb.append("%)");
17888                    Slog.i(TAG, sb.toString());
17889                }
17890                // If a process has held a wake lock for more
17891                // than 50% of the time during this period,
17892                // that sounds bad.  Kill!
17893                if (doWakeKills && realtimeSince > 0
17894                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17895                    synchronized (stats) {
17896                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17897                                realtimeSince, wtimeUsed);
17898                    }
17899                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17900                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17901                } else if (doCpuKills && uptimeSince > 0
17902                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17903                    synchronized (stats) {
17904                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17905                                uptimeSince, cputimeUsed);
17906                    }
17907                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17908                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17909                } else {
17910                    app.lastWakeTime = wtime;
17911                    app.lastCpuTime = app.curCpuTime;
17912                }
17913            }
17914        }
17915    }
17916
17917    private final boolean applyOomAdjLocked(ProcessRecord app,
17918            ProcessRecord TOP_APP, boolean doingAll, long now) {
17919        boolean success = true;
17920
17921        if (app.curRawAdj != app.setRawAdj) {
17922            app.setRawAdj = app.curRawAdj;
17923        }
17924
17925        int changes = 0;
17926
17927        if (app.curAdj != app.setAdj) {
17928            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17929            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17930                TAG, "Set " + app.pid + " " + app.processName +
17931                " adj " + app.curAdj + ": " + app.adjType);
17932            app.setAdj = app.curAdj;
17933        }
17934
17935        if (app.setSchedGroup != app.curSchedGroup) {
17936            app.setSchedGroup = app.curSchedGroup;
17937            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17938                    "Setting process group of " + app.processName
17939                    + " to " + app.curSchedGroup);
17940            if (app.waitingToKill != null &&
17941                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17942                app.kill(app.waitingToKill, true);
17943                success = false;
17944            } else {
17945                if (true) {
17946                    long oldId = Binder.clearCallingIdentity();
17947                    try {
17948                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17949                    } catch (Exception e) {
17950                        Slog.w(TAG, "Failed setting process group of " + app.pid
17951                                + " to " + app.curSchedGroup);
17952                        e.printStackTrace();
17953                    } finally {
17954                        Binder.restoreCallingIdentity(oldId);
17955                    }
17956                } else {
17957                    if (app.thread != null) {
17958                        try {
17959                            app.thread.setSchedulingGroup(app.curSchedGroup);
17960                        } catch (RemoteException e) {
17961                        }
17962                    }
17963                }
17964                Process.setSwappiness(app.pid,
17965                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17966            }
17967        }
17968        if (app.repForegroundActivities != app.foregroundActivities) {
17969            app.repForegroundActivities = app.foregroundActivities;
17970            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17971        }
17972        if (app.repProcState != app.curProcState) {
17973            app.repProcState = app.curProcState;
17974            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17975            if (app.thread != null) {
17976                try {
17977                    if (false) {
17978                        //RuntimeException h = new RuntimeException("here");
17979                        Slog.i(TAG, "Sending new process state " + app.repProcState
17980                                + " to " + app /*, h*/);
17981                    }
17982                    app.thread.setProcessState(app.repProcState);
17983                } catch (RemoteException e) {
17984                }
17985            }
17986        }
17987        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
17988                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
17989            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17990                // Experimental code to more aggressively collect pss while
17991                // running test...  the problem is that this tends to collect
17992                // the data right when a process is transitioning between process
17993                // states, which well tend to give noisy data.
17994                long start = SystemClock.uptimeMillis();
17995                long pss = Debug.getPss(app.pid, mTmpLong, null);
17996                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17997                mPendingPssProcesses.remove(app);
17998                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17999                        + " to " + app.curProcState + ": "
18000                        + (SystemClock.uptimeMillis()-start) + "ms");
18001            }
18002            app.lastStateTime = now;
18003            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18004                    mTestPssMode, isSleeping(), now);
18005            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
18006                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18007                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18008                    + (app.nextPssTime-now) + ": " + app);
18009        } else {
18010            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18011                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18012                    mTestPssMode)))) {
18013                requestPssLocked(app, app.setProcState);
18014                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18015                        mTestPssMode, isSleeping(), now);
18016            } else if (false && DEBUG_PSS) {
18017                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18018            }
18019        }
18020        if (app.setProcState != app.curProcState) {
18021            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18022                    "Proc state change of " + app.processName
18023                    + " to " + app.curProcState);
18024            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18025            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18026            if (setImportant && !curImportant) {
18027                // This app is no longer something we consider important enough to allow to
18028                // use arbitrary amounts of battery power.  Note
18029                // its current wake lock time to later know to kill it if
18030                // it is not behaving well.
18031                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18032                synchronized (stats) {
18033                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18034                            app.pid, SystemClock.elapsedRealtime());
18035                }
18036                app.lastCpuTime = app.curCpuTime;
18037
18038            }
18039            app.setProcState = app.curProcState;
18040            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18041                app.notCachedSinceIdle = false;
18042            }
18043            if (!doingAll) {
18044                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18045            } else {
18046                app.procStateChanged = true;
18047            }
18048        }
18049
18050        if (changes != 0) {
18051            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18052            int i = mPendingProcessChanges.size()-1;
18053            ProcessChangeItem item = null;
18054            while (i >= 0) {
18055                item = mPendingProcessChanges.get(i);
18056                if (item.pid == app.pid) {
18057                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18058                    break;
18059                }
18060                i--;
18061            }
18062            if (i < 0) {
18063                // No existing item in pending changes; need a new one.
18064                final int NA = mAvailProcessChanges.size();
18065                if (NA > 0) {
18066                    item = mAvailProcessChanges.remove(NA-1);
18067                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18068                } else {
18069                    item = new ProcessChangeItem();
18070                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18071                }
18072                item.changes = 0;
18073                item.pid = app.pid;
18074                item.uid = app.info.uid;
18075                if (mPendingProcessChanges.size() == 0) {
18076                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18077                            "*** Enqueueing dispatch processes changed!");
18078                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18079                }
18080                mPendingProcessChanges.add(item);
18081            }
18082            item.changes |= changes;
18083            item.processState = app.repProcState;
18084            item.foregroundActivities = app.repForegroundActivities;
18085            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18086                    + Integer.toHexString(System.identityHashCode(item))
18087                    + " " + app.toShortString() + ": changes=" + item.changes
18088                    + " procState=" + item.processState
18089                    + " foreground=" + item.foregroundActivities
18090                    + " type=" + app.adjType + " source=" + app.adjSource
18091                    + " target=" + app.adjTarget);
18092        }
18093
18094        return success;
18095    }
18096
18097    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18098        if (proc.thread != null) {
18099            if (proc.baseProcessTracker != null) {
18100                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18101            }
18102            if (proc.repProcState >= 0) {
18103                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18104                        proc.repProcState);
18105            }
18106        }
18107    }
18108
18109    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18110            ProcessRecord TOP_APP, boolean doingAll, long now) {
18111        if (app.thread == null) {
18112            return false;
18113        }
18114
18115        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18116
18117        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18118    }
18119
18120    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18121            boolean oomAdj) {
18122        if (isForeground != proc.foregroundServices) {
18123            proc.foregroundServices = isForeground;
18124            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18125                    proc.info.uid);
18126            if (isForeground) {
18127                if (curProcs == null) {
18128                    curProcs = new ArrayList<ProcessRecord>();
18129                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18130                }
18131                if (!curProcs.contains(proc)) {
18132                    curProcs.add(proc);
18133                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18134                            proc.info.packageName, proc.info.uid);
18135                }
18136            } else {
18137                if (curProcs != null) {
18138                    if (curProcs.remove(proc)) {
18139                        mBatteryStatsService.noteEvent(
18140                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18141                                proc.info.packageName, proc.info.uid);
18142                        if (curProcs.size() <= 0) {
18143                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18144                        }
18145                    }
18146                }
18147            }
18148            if (oomAdj) {
18149                updateOomAdjLocked();
18150            }
18151        }
18152    }
18153
18154    private final ActivityRecord resumedAppLocked() {
18155        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18156        String pkg;
18157        int uid;
18158        if (act != null) {
18159            pkg = act.packageName;
18160            uid = act.info.applicationInfo.uid;
18161        } else {
18162            pkg = null;
18163            uid = -1;
18164        }
18165        // Has the UID or resumed package name changed?
18166        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18167                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18168            if (mCurResumedPackage != null) {
18169                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18170                        mCurResumedPackage, mCurResumedUid);
18171            }
18172            mCurResumedPackage = pkg;
18173            mCurResumedUid = uid;
18174            if (mCurResumedPackage != null) {
18175                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18176                        mCurResumedPackage, mCurResumedUid);
18177            }
18178        }
18179        return act;
18180    }
18181
18182    final boolean updateOomAdjLocked(ProcessRecord app) {
18183        final ActivityRecord TOP_ACT = resumedAppLocked();
18184        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18185        final boolean wasCached = app.cached;
18186
18187        mAdjSeq++;
18188
18189        // This is the desired cached adjusment we want to tell it to use.
18190        // If our app is currently cached, we know it, and that is it.  Otherwise,
18191        // we don't know it yet, and it needs to now be cached we will then
18192        // need to do a complete oom adj.
18193        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18194                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18195        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18196                SystemClock.uptimeMillis());
18197        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18198            // Changed to/from cached state, so apps after it in the LRU
18199            // list may also be changed.
18200            updateOomAdjLocked();
18201        }
18202        return success;
18203    }
18204
18205    final void updateOomAdjLocked() {
18206        final ActivityRecord TOP_ACT = resumedAppLocked();
18207        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18208        final long now = SystemClock.uptimeMillis();
18209        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18210        final int N = mLruProcesses.size();
18211
18212        if (false) {
18213            RuntimeException e = new RuntimeException();
18214            e.fillInStackTrace();
18215            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18216        }
18217
18218        mAdjSeq++;
18219        mNewNumServiceProcs = 0;
18220        mNewNumAServiceProcs = 0;
18221
18222        final int emptyProcessLimit;
18223        final int cachedProcessLimit;
18224        if (mProcessLimit <= 0) {
18225            emptyProcessLimit = cachedProcessLimit = 0;
18226        } else if (mProcessLimit == 1) {
18227            emptyProcessLimit = 1;
18228            cachedProcessLimit = 0;
18229        } else {
18230            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18231            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18232        }
18233
18234        // Let's determine how many processes we have running vs.
18235        // how many slots we have for background processes; we may want
18236        // to put multiple processes in a slot of there are enough of
18237        // them.
18238        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18239                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18240        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18241        if (numEmptyProcs > cachedProcessLimit) {
18242            // If there are more empty processes than our limit on cached
18243            // processes, then use the cached process limit for the factor.
18244            // This ensures that the really old empty processes get pushed
18245            // down to the bottom, so if we are running low on memory we will
18246            // have a better chance at keeping around more cached processes
18247            // instead of a gazillion empty processes.
18248            numEmptyProcs = cachedProcessLimit;
18249        }
18250        int emptyFactor = numEmptyProcs/numSlots;
18251        if (emptyFactor < 1) emptyFactor = 1;
18252        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18253        if (cachedFactor < 1) cachedFactor = 1;
18254        int stepCached = 0;
18255        int stepEmpty = 0;
18256        int numCached = 0;
18257        int numEmpty = 0;
18258        int numTrimming = 0;
18259
18260        mNumNonCachedProcs = 0;
18261        mNumCachedHiddenProcs = 0;
18262
18263        // First update the OOM adjustment for each of the
18264        // application processes based on their current state.
18265        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18266        int nextCachedAdj = curCachedAdj+1;
18267        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18268        int nextEmptyAdj = curEmptyAdj+2;
18269        for (int i=N-1; i>=0; i--) {
18270            ProcessRecord app = mLruProcesses.get(i);
18271            if (!app.killedByAm && app.thread != null) {
18272                app.procStateChanged = false;
18273                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18274
18275                // If we haven't yet assigned the final cached adj
18276                // to the process, do that now.
18277                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18278                    switch (app.curProcState) {
18279                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18280                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18281                            // This process is a cached process holding activities...
18282                            // assign it the next cached value for that type, and then
18283                            // step that cached level.
18284                            app.curRawAdj = curCachedAdj;
18285                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18286                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18287                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18288                                    + ")");
18289                            if (curCachedAdj != nextCachedAdj) {
18290                                stepCached++;
18291                                if (stepCached >= cachedFactor) {
18292                                    stepCached = 0;
18293                                    curCachedAdj = nextCachedAdj;
18294                                    nextCachedAdj += 2;
18295                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18296                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18297                                    }
18298                                }
18299                            }
18300                            break;
18301                        default:
18302                            // For everything else, assign next empty cached process
18303                            // level and bump that up.  Note that this means that
18304                            // long-running services that have dropped down to the
18305                            // cached level will be treated as empty (since their process
18306                            // state is still as a service), which is what we want.
18307                            app.curRawAdj = curEmptyAdj;
18308                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18309                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18310                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18311                                    + ")");
18312                            if (curEmptyAdj != nextEmptyAdj) {
18313                                stepEmpty++;
18314                                if (stepEmpty >= emptyFactor) {
18315                                    stepEmpty = 0;
18316                                    curEmptyAdj = nextEmptyAdj;
18317                                    nextEmptyAdj += 2;
18318                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18319                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18320                                    }
18321                                }
18322                            }
18323                            break;
18324                    }
18325                }
18326
18327                applyOomAdjLocked(app, TOP_APP, true, now);
18328
18329                // Count the number of process types.
18330                switch (app.curProcState) {
18331                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18332                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18333                        mNumCachedHiddenProcs++;
18334                        numCached++;
18335                        if (numCached > cachedProcessLimit) {
18336                            app.kill("cached #" + numCached, true);
18337                        }
18338                        break;
18339                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18340                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18341                                && app.lastActivityTime < oldTime) {
18342                            app.kill("empty for "
18343                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18344                                    / 1000) + "s", true);
18345                        } else {
18346                            numEmpty++;
18347                            if (numEmpty > emptyProcessLimit) {
18348                                app.kill("empty #" + numEmpty, true);
18349                            }
18350                        }
18351                        break;
18352                    default:
18353                        mNumNonCachedProcs++;
18354                        break;
18355                }
18356
18357                if (app.isolated && app.services.size() <= 0) {
18358                    // If this is an isolated process, and there are no
18359                    // services running in it, then the process is no longer
18360                    // needed.  We agressively kill these because we can by
18361                    // definition not re-use the same process again, and it is
18362                    // good to avoid having whatever code was running in them
18363                    // left sitting around after no longer needed.
18364                    app.kill("isolated not needed", true);
18365                }
18366
18367                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18368                        && !app.killedByAm) {
18369                    numTrimming++;
18370                }
18371            }
18372        }
18373
18374        mNumServiceProcs = mNewNumServiceProcs;
18375
18376        // Now determine the memory trimming level of background processes.
18377        // Unfortunately we need to start at the back of the list to do this
18378        // properly.  We only do this if the number of background apps we
18379        // are managing to keep around is less than half the maximum we desire;
18380        // if we are keeping a good number around, we'll let them use whatever
18381        // memory they want.
18382        final int numCachedAndEmpty = numCached + numEmpty;
18383        int memFactor;
18384        if (numCached <= ProcessList.TRIM_CACHED_APPS
18385                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18386            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18387                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18388            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18389                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18390            } else {
18391                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18392            }
18393        } else {
18394            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18395        }
18396        // We always allow the memory level to go up (better).  We only allow it to go
18397        // down if we are in a state where that is allowed, *and* the total number of processes
18398        // has gone down since last time.
18399        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18400                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18401                + " last=" + mLastNumProcesses);
18402        if (memFactor > mLastMemoryLevel) {
18403            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18404                memFactor = mLastMemoryLevel;
18405                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18406            }
18407        }
18408        mLastMemoryLevel = memFactor;
18409        mLastNumProcesses = mLruProcesses.size();
18410        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18411        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18412        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18413            if (mLowRamStartTime == 0) {
18414                mLowRamStartTime = now;
18415            }
18416            int step = 0;
18417            int fgTrimLevel;
18418            switch (memFactor) {
18419                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18420                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18421                    break;
18422                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18423                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18424                    break;
18425                default:
18426                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18427                    break;
18428            }
18429            int factor = numTrimming/3;
18430            int minFactor = 2;
18431            if (mHomeProcess != null) minFactor++;
18432            if (mPreviousProcess != null) minFactor++;
18433            if (factor < minFactor) factor = minFactor;
18434            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18435            for (int i=N-1; i>=0; i--) {
18436                ProcessRecord app = mLruProcesses.get(i);
18437                if (allChanged || app.procStateChanged) {
18438                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18439                    app.procStateChanged = false;
18440                }
18441                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18442                        && !app.killedByAm) {
18443                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18444                        try {
18445                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18446                                    "Trimming memory of " + app.processName
18447                                    + " to " + curLevel);
18448                            app.thread.scheduleTrimMemory(curLevel);
18449                        } catch (RemoteException e) {
18450                        }
18451                        if (false) {
18452                            // For now we won't do this; our memory trimming seems
18453                            // to be good enough at this point that destroying
18454                            // activities causes more harm than good.
18455                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18456                                    && app != mHomeProcess && app != mPreviousProcess) {
18457                                // Need to do this on its own message because the stack may not
18458                                // be in a consistent state at this point.
18459                                // For these apps we will also finish their activities
18460                                // to help them free memory.
18461                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18462                            }
18463                        }
18464                    }
18465                    app.trimMemoryLevel = curLevel;
18466                    step++;
18467                    if (step >= factor) {
18468                        step = 0;
18469                        switch (curLevel) {
18470                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18471                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18472                                break;
18473                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18474                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18475                                break;
18476                        }
18477                    }
18478                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18479                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18480                            && app.thread != null) {
18481                        try {
18482                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18483                                    "Trimming memory of heavy-weight " + app.processName
18484                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18485                            app.thread.scheduleTrimMemory(
18486                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18487                        } catch (RemoteException e) {
18488                        }
18489                    }
18490                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18491                } else {
18492                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18493                            || app.systemNoUi) && app.pendingUiClean) {
18494                        // If this application is now in the background and it
18495                        // had done UI, then give it the special trim level to
18496                        // have it free UI resources.
18497                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18498                        if (app.trimMemoryLevel < level && app.thread != null) {
18499                            try {
18500                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18501                                        "Trimming memory of bg-ui " + app.processName
18502                                        + " to " + level);
18503                                app.thread.scheduleTrimMemory(level);
18504                            } catch (RemoteException e) {
18505                            }
18506                        }
18507                        app.pendingUiClean = false;
18508                    }
18509                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18510                        try {
18511                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18512                                    "Trimming memory of fg " + app.processName
18513                                    + " to " + fgTrimLevel);
18514                            app.thread.scheduleTrimMemory(fgTrimLevel);
18515                        } catch (RemoteException e) {
18516                        }
18517                    }
18518                    app.trimMemoryLevel = fgTrimLevel;
18519                }
18520            }
18521        } else {
18522            if (mLowRamStartTime != 0) {
18523                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18524                mLowRamStartTime = 0;
18525            }
18526            for (int i=N-1; i>=0; i--) {
18527                ProcessRecord app = mLruProcesses.get(i);
18528                if (allChanged || app.procStateChanged) {
18529                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18530                    app.procStateChanged = false;
18531                }
18532                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18533                        || app.systemNoUi) && app.pendingUiClean) {
18534                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18535                            && app.thread != null) {
18536                        try {
18537                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18538                                    "Trimming memory of ui hidden " + app.processName
18539                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18540                            app.thread.scheduleTrimMemory(
18541                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18542                        } catch (RemoteException e) {
18543                        }
18544                    }
18545                    app.pendingUiClean = false;
18546                }
18547                app.trimMemoryLevel = 0;
18548            }
18549        }
18550
18551        if (mAlwaysFinishActivities) {
18552            // Need to do this on its own message because the stack may not
18553            // be in a consistent state at this point.
18554            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18555        }
18556
18557        if (allChanged) {
18558            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18559        }
18560
18561        if (mProcessStats.shouldWriteNowLocked(now)) {
18562            mHandler.post(new Runnable() {
18563                @Override public void run() {
18564                    synchronized (ActivityManagerService.this) {
18565                        mProcessStats.writeStateAsyncLocked();
18566                    }
18567                }
18568            });
18569        }
18570
18571        if (DEBUG_OOM_ADJ) {
18572            if (false) {
18573                RuntimeException here = new RuntimeException("here");
18574                here.fillInStackTrace();
18575                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18576            } else {
18577                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18578            }
18579        }
18580    }
18581
18582    final void trimApplications() {
18583        synchronized (this) {
18584            int i;
18585
18586            // First remove any unused application processes whose package
18587            // has been removed.
18588            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18589                final ProcessRecord app = mRemovedProcesses.get(i);
18590                if (app.activities.size() == 0
18591                        && app.curReceiver == null && app.services.size() == 0) {
18592                    Slog.i(
18593                        TAG, "Exiting empty application process "
18594                        + app.processName + " ("
18595                        + (app.thread != null ? app.thread.asBinder() : null)
18596                        + ")\n");
18597                    if (app.pid > 0 && app.pid != MY_PID) {
18598                        app.kill("empty", false);
18599                    } else {
18600                        try {
18601                            app.thread.scheduleExit();
18602                        } catch (Exception e) {
18603                            // Ignore exceptions.
18604                        }
18605                    }
18606                    cleanUpApplicationRecordLocked(app, false, true, -1);
18607                    mRemovedProcesses.remove(i);
18608
18609                    if (app.persistent) {
18610                        addAppLocked(app.info, false, null /* ABI override */);
18611                    }
18612                }
18613            }
18614
18615            // Now update the oom adj for all processes.
18616            updateOomAdjLocked();
18617        }
18618    }
18619
18620    /** This method sends the specified signal to each of the persistent apps */
18621    public void signalPersistentProcesses(int sig) throws RemoteException {
18622        if (sig != Process.SIGNAL_USR1) {
18623            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18624        }
18625
18626        synchronized (this) {
18627            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18628                    != PackageManager.PERMISSION_GRANTED) {
18629                throw new SecurityException("Requires permission "
18630                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18631            }
18632
18633            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18634                ProcessRecord r = mLruProcesses.get(i);
18635                if (r.thread != null && r.persistent) {
18636                    Process.sendSignal(r.pid, sig);
18637                }
18638            }
18639        }
18640    }
18641
18642    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18643        if (proc == null || proc == mProfileProc) {
18644            proc = mProfileProc;
18645            profileType = mProfileType;
18646            clearProfilerLocked();
18647        }
18648        if (proc == null) {
18649            return;
18650        }
18651        try {
18652            proc.thread.profilerControl(false, null, profileType);
18653        } catch (RemoteException e) {
18654            throw new IllegalStateException("Process disappeared");
18655        }
18656    }
18657
18658    private void clearProfilerLocked() {
18659        if (mProfileFd != null) {
18660            try {
18661                mProfileFd.close();
18662            } catch (IOException e) {
18663            }
18664        }
18665        mProfileApp = null;
18666        mProfileProc = null;
18667        mProfileFile = null;
18668        mProfileType = 0;
18669        mAutoStopProfiler = false;
18670        mSamplingInterval = 0;
18671    }
18672
18673    public boolean profileControl(String process, int userId, boolean start,
18674            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18675
18676        try {
18677            synchronized (this) {
18678                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18679                // its own permission.
18680                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18681                        != PackageManager.PERMISSION_GRANTED) {
18682                    throw new SecurityException("Requires permission "
18683                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18684                }
18685
18686                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18687                    throw new IllegalArgumentException("null profile info or fd");
18688                }
18689
18690                ProcessRecord proc = null;
18691                if (process != null) {
18692                    proc = findProcessLocked(process, userId, "profileControl");
18693                }
18694
18695                if (start && (proc == null || proc.thread == null)) {
18696                    throw new IllegalArgumentException("Unknown process: " + process);
18697                }
18698
18699                if (start) {
18700                    stopProfilerLocked(null, 0);
18701                    setProfileApp(proc.info, proc.processName, profilerInfo);
18702                    mProfileProc = proc;
18703                    mProfileType = profileType;
18704                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18705                    try {
18706                        fd = fd.dup();
18707                    } catch (IOException e) {
18708                        fd = null;
18709                    }
18710                    profilerInfo.profileFd = fd;
18711                    proc.thread.profilerControl(start, profilerInfo, profileType);
18712                    fd = null;
18713                    mProfileFd = null;
18714                } else {
18715                    stopProfilerLocked(proc, profileType);
18716                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18717                        try {
18718                            profilerInfo.profileFd.close();
18719                        } catch (IOException e) {
18720                        }
18721                    }
18722                }
18723
18724                return true;
18725            }
18726        } catch (RemoteException e) {
18727            throw new IllegalStateException("Process disappeared");
18728        } finally {
18729            if (profilerInfo != null && profilerInfo.profileFd != null) {
18730                try {
18731                    profilerInfo.profileFd.close();
18732                } catch (IOException e) {
18733                }
18734            }
18735        }
18736    }
18737
18738    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18739        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18740                userId, true, ALLOW_FULL_ONLY, callName, null);
18741        ProcessRecord proc = null;
18742        try {
18743            int pid = Integer.parseInt(process);
18744            synchronized (mPidsSelfLocked) {
18745                proc = mPidsSelfLocked.get(pid);
18746            }
18747        } catch (NumberFormatException e) {
18748        }
18749
18750        if (proc == null) {
18751            ArrayMap<String, SparseArray<ProcessRecord>> all
18752                    = mProcessNames.getMap();
18753            SparseArray<ProcessRecord> procs = all.get(process);
18754            if (procs != null && procs.size() > 0) {
18755                proc = procs.valueAt(0);
18756                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18757                    for (int i=1; i<procs.size(); i++) {
18758                        ProcessRecord thisProc = procs.valueAt(i);
18759                        if (thisProc.userId == userId) {
18760                            proc = thisProc;
18761                            break;
18762                        }
18763                    }
18764                }
18765            }
18766        }
18767
18768        return proc;
18769    }
18770
18771    public boolean dumpHeap(String process, int userId, boolean managed,
18772            String path, ParcelFileDescriptor fd) throws RemoteException {
18773
18774        try {
18775            synchronized (this) {
18776                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18777                // its own permission (same as profileControl).
18778                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18779                        != PackageManager.PERMISSION_GRANTED) {
18780                    throw new SecurityException("Requires permission "
18781                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18782                }
18783
18784                if (fd == null) {
18785                    throw new IllegalArgumentException("null fd");
18786                }
18787
18788                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18789                if (proc == null || proc.thread == null) {
18790                    throw new IllegalArgumentException("Unknown process: " + process);
18791                }
18792
18793                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18794                if (!isDebuggable) {
18795                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18796                        throw new SecurityException("Process not debuggable: " + proc);
18797                    }
18798                }
18799
18800                proc.thread.dumpHeap(managed, path, fd);
18801                fd = null;
18802                return true;
18803            }
18804        } catch (RemoteException e) {
18805            throw new IllegalStateException("Process disappeared");
18806        } finally {
18807            if (fd != null) {
18808                try {
18809                    fd.close();
18810                } catch (IOException e) {
18811                }
18812            }
18813        }
18814    }
18815
18816    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18817    public void monitor() {
18818        synchronized (this) { }
18819    }
18820
18821    void onCoreSettingsChange(Bundle settings) {
18822        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18823            ProcessRecord processRecord = mLruProcesses.get(i);
18824            try {
18825                if (processRecord.thread != null) {
18826                    processRecord.thread.setCoreSettings(settings);
18827                }
18828            } catch (RemoteException re) {
18829                /* ignore */
18830            }
18831        }
18832    }
18833
18834    // Multi-user methods
18835
18836    /**
18837     * Start user, if its not already running, but don't bring it to foreground.
18838     */
18839    @Override
18840    public boolean startUserInBackground(final int userId) {
18841        return startUser(userId, /* foreground */ false);
18842    }
18843
18844    /**
18845     * Start user, if its not already running, and bring it to foreground.
18846     */
18847    boolean startUserInForeground(final int userId, Dialog dlg) {
18848        boolean result = startUser(userId, /* foreground */ true);
18849        dlg.dismiss();
18850        return result;
18851    }
18852
18853    /**
18854     * Refreshes the list of users related to the current user when either a
18855     * user switch happens or when a new related user is started in the
18856     * background.
18857     */
18858    private void updateCurrentProfileIdsLocked() {
18859        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18860                mCurrentUserId, false /* enabledOnly */);
18861        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18862        for (int i = 0; i < currentProfileIds.length; i++) {
18863            currentProfileIds[i] = profiles.get(i).id;
18864        }
18865        mCurrentProfileIds = currentProfileIds;
18866
18867        synchronized (mUserProfileGroupIdsSelfLocked) {
18868            mUserProfileGroupIdsSelfLocked.clear();
18869            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18870            for (int i = 0; i < users.size(); i++) {
18871                UserInfo user = users.get(i);
18872                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18873                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18874                }
18875            }
18876        }
18877    }
18878
18879    private Set getProfileIdsLocked(int userId) {
18880        Set userIds = new HashSet<Integer>();
18881        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18882                userId, false /* enabledOnly */);
18883        for (UserInfo user : profiles) {
18884            userIds.add(Integer.valueOf(user.id));
18885        }
18886        return userIds;
18887    }
18888
18889    @Override
18890    public boolean switchUser(final int userId) {
18891        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18892        String userName;
18893        synchronized (this) {
18894            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18895            if (userInfo == null) {
18896                Slog.w(TAG, "No user info for user #" + userId);
18897                return false;
18898            }
18899            if (userInfo.isManagedProfile()) {
18900                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18901                return false;
18902            }
18903            userName = userInfo.name;
18904            mTargetUserId = userId;
18905        }
18906        mHandler.removeMessages(START_USER_SWITCH_MSG);
18907        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18908        return true;
18909    }
18910
18911    private void showUserSwitchDialog(int userId, String userName) {
18912        // The dialog will show and then initiate the user switch by calling startUserInForeground
18913        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18914                true /* above system */);
18915        d.show();
18916    }
18917
18918    private boolean startUser(final int userId, final boolean foreground) {
18919        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18920                != PackageManager.PERMISSION_GRANTED) {
18921            String msg = "Permission Denial: switchUser() from pid="
18922                    + Binder.getCallingPid()
18923                    + ", uid=" + Binder.getCallingUid()
18924                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18925            Slog.w(TAG, msg);
18926            throw new SecurityException(msg);
18927        }
18928
18929        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18930
18931        final long ident = Binder.clearCallingIdentity();
18932        try {
18933            synchronized (this) {
18934                final int oldUserId = mCurrentUserId;
18935                if (oldUserId == userId) {
18936                    return true;
18937                }
18938
18939                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18940
18941                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18942                if (userInfo == null) {
18943                    Slog.w(TAG, "No user info for user #" + userId);
18944                    return false;
18945                }
18946                if (foreground && userInfo.isManagedProfile()) {
18947                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18948                    return false;
18949                }
18950
18951                if (foreground) {
18952                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18953                            R.anim.screen_user_enter);
18954                }
18955
18956                boolean needStart = false;
18957
18958                // If the user we are switching to is not currently started, then
18959                // we need to start it now.
18960                if (mStartedUsers.get(userId) == null) {
18961                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18962                    updateStartedUserArrayLocked();
18963                    needStart = true;
18964                }
18965
18966                final Integer userIdInt = Integer.valueOf(userId);
18967                mUserLru.remove(userIdInt);
18968                mUserLru.add(userIdInt);
18969
18970                if (foreground) {
18971                    mCurrentUserId = userId;
18972                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18973                    updateCurrentProfileIdsLocked();
18974                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18975                    // Once the internal notion of the active user has switched, we lock the device
18976                    // with the option to show the user switcher on the keyguard.
18977                    mWindowManager.lockNow(null);
18978                } else {
18979                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18980                    updateCurrentProfileIdsLocked();
18981                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18982                    mUserLru.remove(currentUserIdInt);
18983                    mUserLru.add(currentUserIdInt);
18984                }
18985
18986                final UserStartedState uss = mStartedUsers.get(userId);
18987
18988                // Make sure user is in the started state.  If it is currently
18989                // stopping, we need to knock that off.
18990                if (uss.mState == UserStartedState.STATE_STOPPING) {
18991                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18992                    // so we can just fairly silently bring the user back from
18993                    // the almost-dead.
18994                    uss.mState = UserStartedState.STATE_RUNNING;
18995                    updateStartedUserArrayLocked();
18996                    needStart = true;
18997                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18998                    // This means ACTION_SHUTDOWN has been sent, so we will
18999                    // need to treat this as a new boot of the user.
19000                    uss.mState = UserStartedState.STATE_BOOTING;
19001                    updateStartedUserArrayLocked();
19002                    needStart = true;
19003                }
19004
19005                if (uss.mState == UserStartedState.STATE_BOOTING) {
19006                    // Booting up a new user, need to tell system services about it.
19007                    // Note that this is on the same handler as scheduling of broadcasts,
19008                    // which is important because it needs to go first.
19009                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19010                }
19011
19012                if (foreground) {
19013                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19014                            oldUserId));
19015                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19016                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19017                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19018                            oldUserId, userId, uss));
19019                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19020                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19021                }
19022
19023                if (needStart) {
19024                    // Send USER_STARTED broadcast
19025                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19026                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19027                            | Intent.FLAG_RECEIVER_FOREGROUND);
19028                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19029                    broadcastIntentLocked(null, null, intent,
19030                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19031                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19032                }
19033
19034                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19035                    if (userId != UserHandle.USER_OWNER) {
19036                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19037                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19038                        broadcastIntentLocked(null, null, intent, null,
19039                                new IIntentReceiver.Stub() {
19040                                    public void performReceive(Intent intent, int resultCode,
19041                                            String data, Bundle extras, boolean ordered,
19042                                            boolean sticky, int sendingUser) {
19043                                        onUserInitialized(uss, foreground, oldUserId, userId);
19044                                    }
19045                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19046                                true, false, MY_PID, Process.SYSTEM_UID,
19047                                userId);
19048                        uss.initializing = true;
19049                    } else {
19050                        getUserManagerLocked().makeInitialized(userInfo.id);
19051                    }
19052                }
19053
19054                if (foreground) {
19055                    if (!uss.initializing) {
19056                        moveUserToForeground(uss, oldUserId, userId);
19057                    }
19058                } else {
19059                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19060                }
19061
19062                if (needStart) {
19063                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19064                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19065                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19066                    broadcastIntentLocked(null, null, intent,
19067                            null, new IIntentReceiver.Stub() {
19068                                @Override
19069                                public void performReceive(Intent intent, int resultCode, String data,
19070                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19071                                        throws RemoteException {
19072                                }
19073                            }, 0, null, null,
19074                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19075                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19076                }
19077            }
19078        } finally {
19079            Binder.restoreCallingIdentity(ident);
19080        }
19081
19082        return true;
19083    }
19084
19085    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19086        long ident = Binder.clearCallingIdentity();
19087        try {
19088            Intent intent;
19089            if (oldUserId >= 0) {
19090                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19091                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19092                int count = profiles.size();
19093                for (int i = 0; i < count; i++) {
19094                    int profileUserId = profiles.get(i).id;
19095                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19096                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19097                            | Intent.FLAG_RECEIVER_FOREGROUND);
19098                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19099                    broadcastIntentLocked(null, null, intent,
19100                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19101                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19102                }
19103            }
19104            if (newUserId >= 0) {
19105                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19106                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19107                int count = profiles.size();
19108                for (int i = 0; i < count; i++) {
19109                    int profileUserId = profiles.get(i).id;
19110                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19111                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19112                            | Intent.FLAG_RECEIVER_FOREGROUND);
19113                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19114                    broadcastIntentLocked(null, null, intent,
19115                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19116                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19117                }
19118                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19120                        | Intent.FLAG_RECEIVER_FOREGROUND);
19121                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19122                broadcastIntentLocked(null, null, intent,
19123                        null, null, 0, null, null,
19124                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19125                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19126            }
19127        } finally {
19128            Binder.restoreCallingIdentity(ident);
19129        }
19130    }
19131
19132    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19133            final int newUserId) {
19134        final int N = mUserSwitchObservers.beginBroadcast();
19135        if (N > 0) {
19136            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19137                int mCount = 0;
19138                @Override
19139                public void sendResult(Bundle data) throws RemoteException {
19140                    synchronized (ActivityManagerService.this) {
19141                        if (mCurUserSwitchCallback == this) {
19142                            mCount++;
19143                            if (mCount == N) {
19144                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19145                            }
19146                        }
19147                    }
19148                }
19149            };
19150            synchronized (this) {
19151                uss.switching = true;
19152                mCurUserSwitchCallback = callback;
19153            }
19154            for (int i=0; i<N; i++) {
19155                try {
19156                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19157                            newUserId, callback);
19158                } catch (RemoteException e) {
19159                }
19160            }
19161        } else {
19162            synchronized (this) {
19163                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19164            }
19165        }
19166        mUserSwitchObservers.finishBroadcast();
19167    }
19168
19169    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19170        synchronized (this) {
19171            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19172            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19173        }
19174    }
19175
19176    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19177        mCurUserSwitchCallback = null;
19178        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19179        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19180                oldUserId, newUserId, uss));
19181    }
19182
19183    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19184        synchronized (this) {
19185            if (foreground) {
19186                moveUserToForeground(uss, oldUserId, newUserId);
19187            }
19188        }
19189
19190        completeSwitchAndInitalize(uss, newUserId, true, false);
19191    }
19192
19193    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19194        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19195        if (homeInFront) {
19196            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19197        } else {
19198            mStackSupervisor.resumeTopActivitiesLocked();
19199        }
19200        EventLogTags.writeAmSwitchUser(newUserId);
19201        getUserManagerLocked().userForeground(newUserId);
19202        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19203    }
19204
19205    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19206        completeSwitchAndInitalize(uss, newUserId, false, true);
19207    }
19208
19209    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19210            boolean clearInitializing, boolean clearSwitching) {
19211        boolean unfrozen = false;
19212        synchronized (this) {
19213            if (clearInitializing) {
19214                uss.initializing = false;
19215                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19216            }
19217            if (clearSwitching) {
19218                uss.switching = false;
19219            }
19220            if (!uss.switching && !uss.initializing) {
19221                mWindowManager.stopFreezingScreen();
19222                unfrozen = true;
19223            }
19224        }
19225        if (unfrozen) {
19226            final int N = mUserSwitchObservers.beginBroadcast();
19227            for (int i=0; i<N; i++) {
19228                try {
19229                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19230                } catch (RemoteException e) {
19231                }
19232            }
19233            mUserSwitchObservers.finishBroadcast();
19234        }
19235        stopGuestUserIfBackground();
19236    }
19237
19238    /**
19239     * Stops the guest user if it has gone to the background.
19240     */
19241    private void stopGuestUserIfBackground() {
19242        synchronized (this) {
19243            final int num = mUserLru.size();
19244            for (int i = 0; i < num; i++) {
19245                Integer oldUserId = mUserLru.get(i);
19246                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19247                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19248                        || oldUss.mState == UserStartedState.STATE_STOPPING
19249                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19250                    continue;
19251                }
19252                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19253                if (userInfo.isGuest()) {
19254                    // This is a user to be stopped.
19255                    stopUserLocked(oldUserId, null);
19256                    break;
19257                }
19258            }
19259        }
19260    }
19261
19262    void scheduleStartProfilesLocked() {
19263        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19264            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19265                    DateUtils.SECOND_IN_MILLIS);
19266        }
19267    }
19268
19269    void startProfilesLocked() {
19270        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19271        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19272                mCurrentUserId, false /* enabledOnly */);
19273        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19274        for (UserInfo user : profiles) {
19275            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19276                    && user.id != mCurrentUserId) {
19277                toStart.add(user);
19278            }
19279        }
19280        final int n = toStart.size();
19281        int i = 0;
19282        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19283            startUserInBackground(toStart.get(i).id);
19284        }
19285        if (i < n) {
19286            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19287        }
19288    }
19289
19290    void finishUserBoot(UserStartedState uss) {
19291        synchronized (this) {
19292            if (uss.mState == UserStartedState.STATE_BOOTING
19293                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19294                uss.mState = UserStartedState.STATE_RUNNING;
19295                final int userId = uss.mHandle.getIdentifier();
19296                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19297                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19298                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19299                broadcastIntentLocked(null, null, intent,
19300                        null, null, 0, null, null,
19301                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19302                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19303            }
19304        }
19305    }
19306
19307    void finishUserSwitch(UserStartedState uss) {
19308        synchronized (this) {
19309            finishUserBoot(uss);
19310
19311            startProfilesLocked();
19312
19313            int num = mUserLru.size();
19314            int i = 0;
19315            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19316                Integer oldUserId = mUserLru.get(i);
19317                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19318                if (oldUss == null) {
19319                    // Shouldn't happen, but be sane if it does.
19320                    mUserLru.remove(i);
19321                    num--;
19322                    continue;
19323                }
19324                if (oldUss.mState == UserStartedState.STATE_STOPPING
19325                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19326                    // This user is already stopping, doesn't count.
19327                    num--;
19328                    i++;
19329                    continue;
19330                }
19331                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19332                    // Owner and current can't be stopped, but count as running.
19333                    i++;
19334                    continue;
19335                }
19336                // This is a user to be stopped.
19337                stopUserLocked(oldUserId, null);
19338                num--;
19339                i++;
19340            }
19341        }
19342    }
19343
19344    @Override
19345    public int stopUser(final int userId, final IStopUserCallback callback) {
19346        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19347                != PackageManager.PERMISSION_GRANTED) {
19348            String msg = "Permission Denial: switchUser() from pid="
19349                    + Binder.getCallingPid()
19350                    + ", uid=" + Binder.getCallingUid()
19351                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19352            Slog.w(TAG, msg);
19353            throw new SecurityException(msg);
19354        }
19355        if (userId <= 0) {
19356            throw new IllegalArgumentException("Can't stop primary user " + userId);
19357        }
19358        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19359        synchronized (this) {
19360            return stopUserLocked(userId, callback);
19361        }
19362    }
19363
19364    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19365        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19366        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19367            return ActivityManager.USER_OP_IS_CURRENT;
19368        }
19369
19370        final UserStartedState uss = mStartedUsers.get(userId);
19371        if (uss == null) {
19372            // User is not started, nothing to do...  but we do need to
19373            // callback if requested.
19374            if (callback != null) {
19375                mHandler.post(new Runnable() {
19376                    @Override
19377                    public void run() {
19378                        try {
19379                            callback.userStopped(userId);
19380                        } catch (RemoteException e) {
19381                        }
19382                    }
19383                });
19384            }
19385            return ActivityManager.USER_OP_SUCCESS;
19386        }
19387
19388        if (callback != null) {
19389            uss.mStopCallbacks.add(callback);
19390        }
19391
19392        if (uss.mState != UserStartedState.STATE_STOPPING
19393                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19394            uss.mState = UserStartedState.STATE_STOPPING;
19395            updateStartedUserArrayLocked();
19396
19397            long ident = Binder.clearCallingIdentity();
19398            try {
19399                // We are going to broadcast ACTION_USER_STOPPING and then
19400                // once that is done send a final ACTION_SHUTDOWN and then
19401                // stop the user.
19402                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19403                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19404                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19405                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19406                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19407                // This is the result receiver for the final shutdown broadcast.
19408                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19409                    @Override
19410                    public void performReceive(Intent intent, int resultCode, String data,
19411                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19412                        finishUserStop(uss);
19413                    }
19414                };
19415                // This is the result receiver for the initial stopping broadcast.
19416                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19417                    @Override
19418                    public void performReceive(Intent intent, int resultCode, String data,
19419                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19420                        // On to the next.
19421                        synchronized (ActivityManagerService.this) {
19422                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19423                                // Whoops, we are being started back up.  Abort, abort!
19424                                return;
19425                            }
19426                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19427                        }
19428                        mBatteryStatsService.noteEvent(
19429                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19430                                Integer.toString(userId), userId);
19431                        mSystemServiceManager.stopUser(userId);
19432                        broadcastIntentLocked(null, null, shutdownIntent,
19433                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19434                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19435                    }
19436                };
19437                // Kick things off.
19438                broadcastIntentLocked(null, null, stoppingIntent,
19439                        null, stoppingReceiver, 0, null, null,
19440                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19441                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19442            } finally {
19443                Binder.restoreCallingIdentity(ident);
19444            }
19445        }
19446
19447        return ActivityManager.USER_OP_SUCCESS;
19448    }
19449
19450    void finishUserStop(UserStartedState uss) {
19451        final int userId = uss.mHandle.getIdentifier();
19452        boolean stopped;
19453        ArrayList<IStopUserCallback> callbacks;
19454        synchronized (this) {
19455            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19456            if (mStartedUsers.get(userId) != uss) {
19457                stopped = false;
19458            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19459                stopped = false;
19460            } else {
19461                stopped = true;
19462                // User can no longer run.
19463                mStartedUsers.remove(userId);
19464                mUserLru.remove(Integer.valueOf(userId));
19465                updateStartedUserArrayLocked();
19466
19467                // Clean up all state and processes associated with the user.
19468                // Kill all the processes for the user.
19469                forceStopUserLocked(userId, "finish user");
19470            }
19471
19472            // Explicitly remove the old information in mRecentTasks.
19473            removeRecentTasksForUserLocked(userId);
19474        }
19475
19476        for (int i=0; i<callbacks.size(); i++) {
19477            try {
19478                if (stopped) callbacks.get(i).userStopped(userId);
19479                else callbacks.get(i).userStopAborted(userId);
19480            } catch (RemoteException e) {
19481            }
19482        }
19483
19484        if (stopped) {
19485            mSystemServiceManager.cleanupUser(userId);
19486            synchronized (this) {
19487                mStackSupervisor.removeUserLocked(userId);
19488            }
19489        }
19490    }
19491
19492    @Override
19493    public UserInfo getCurrentUser() {
19494        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19495                != PackageManager.PERMISSION_GRANTED) && (
19496                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19497                != PackageManager.PERMISSION_GRANTED)) {
19498            String msg = "Permission Denial: getCurrentUser() from pid="
19499                    + Binder.getCallingPid()
19500                    + ", uid=" + Binder.getCallingUid()
19501                    + " requires " + INTERACT_ACROSS_USERS;
19502            Slog.w(TAG, msg);
19503            throw new SecurityException(msg);
19504        }
19505        synchronized (this) {
19506            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19507            return getUserManagerLocked().getUserInfo(userId);
19508        }
19509    }
19510
19511    int getCurrentUserIdLocked() {
19512        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19513    }
19514
19515    @Override
19516    public boolean isUserRunning(int userId, boolean orStopped) {
19517        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19518                != PackageManager.PERMISSION_GRANTED) {
19519            String msg = "Permission Denial: isUserRunning() from pid="
19520                    + Binder.getCallingPid()
19521                    + ", uid=" + Binder.getCallingUid()
19522                    + " requires " + INTERACT_ACROSS_USERS;
19523            Slog.w(TAG, msg);
19524            throw new SecurityException(msg);
19525        }
19526        synchronized (this) {
19527            return isUserRunningLocked(userId, orStopped);
19528        }
19529    }
19530
19531    boolean isUserRunningLocked(int userId, boolean orStopped) {
19532        UserStartedState state = mStartedUsers.get(userId);
19533        if (state == null) {
19534            return false;
19535        }
19536        if (orStopped) {
19537            return true;
19538        }
19539        return state.mState != UserStartedState.STATE_STOPPING
19540                && state.mState != UserStartedState.STATE_SHUTDOWN;
19541    }
19542
19543    @Override
19544    public int[] getRunningUserIds() {
19545        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19546                != PackageManager.PERMISSION_GRANTED) {
19547            String msg = "Permission Denial: isUserRunning() from pid="
19548                    + Binder.getCallingPid()
19549                    + ", uid=" + Binder.getCallingUid()
19550                    + " requires " + INTERACT_ACROSS_USERS;
19551            Slog.w(TAG, msg);
19552            throw new SecurityException(msg);
19553        }
19554        synchronized (this) {
19555            return mStartedUserArray;
19556        }
19557    }
19558
19559    private void updateStartedUserArrayLocked() {
19560        int num = 0;
19561        for (int i=0; i<mStartedUsers.size();  i++) {
19562            UserStartedState uss = mStartedUsers.valueAt(i);
19563            // This list does not include stopping users.
19564            if (uss.mState != UserStartedState.STATE_STOPPING
19565                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19566                num++;
19567            }
19568        }
19569        mStartedUserArray = new int[num];
19570        num = 0;
19571        for (int i=0; i<mStartedUsers.size();  i++) {
19572            UserStartedState uss = mStartedUsers.valueAt(i);
19573            if (uss.mState != UserStartedState.STATE_STOPPING
19574                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19575                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19576                num++;
19577            }
19578        }
19579    }
19580
19581    @Override
19582    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19583        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19584                != PackageManager.PERMISSION_GRANTED) {
19585            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19586                    + Binder.getCallingPid()
19587                    + ", uid=" + Binder.getCallingUid()
19588                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19589            Slog.w(TAG, msg);
19590            throw new SecurityException(msg);
19591        }
19592
19593        mUserSwitchObservers.register(observer);
19594    }
19595
19596    @Override
19597    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19598        mUserSwitchObservers.unregister(observer);
19599    }
19600
19601    private boolean userExists(int userId) {
19602        if (userId == 0) {
19603            return true;
19604        }
19605        UserManagerService ums = getUserManagerLocked();
19606        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19607    }
19608
19609    int[] getUsersLocked() {
19610        UserManagerService ums = getUserManagerLocked();
19611        return ums != null ? ums.getUserIds() : new int[] { 0 };
19612    }
19613
19614    UserManagerService getUserManagerLocked() {
19615        if (mUserManager == null) {
19616            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19617            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19618        }
19619        return mUserManager;
19620    }
19621
19622    private int applyUserId(int uid, int userId) {
19623        return UserHandle.getUid(userId, uid);
19624    }
19625
19626    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19627        if (info == null) return null;
19628        ApplicationInfo newInfo = new ApplicationInfo(info);
19629        newInfo.uid = applyUserId(info.uid, userId);
19630        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19631                + info.packageName;
19632        return newInfo;
19633    }
19634
19635    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19636        if (aInfo == null
19637                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19638            return aInfo;
19639        }
19640
19641        ActivityInfo info = new ActivityInfo(aInfo);
19642        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19643        return info;
19644    }
19645
19646    private final class LocalService extends ActivityManagerInternal {
19647        @Override
19648        public void onWakefulnessChanged(int wakefulness) {
19649            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19650        }
19651
19652        @Override
19653        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19654                String processName, String abiOverride, int uid, Runnable crashHandler) {
19655            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19656                    processName, abiOverride, uid, crashHandler);
19657        }
19658    }
19659
19660    /**
19661     * An implementation of IAppTask, that allows an app to manage its own tasks via
19662     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19663     * only the process that calls getAppTasks() can call the AppTask methods.
19664     */
19665    class AppTaskImpl extends IAppTask.Stub {
19666        private int mTaskId;
19667        private int mCallingUid;
19668
19669        public AppTaskImpl(int taskId, int callingUid) {
19670            mTaskId = taskId;
19671            mCallingUid = callingUid;
19672        }
19673
19674        private void checkCaller() {
19675            if (mCallingUid != Binder.getCallingUid()) {
19676                throw new SecurityException("Caller " + mCallingUid
19677                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19678            }
19679        }
19680
19681        @Override
19682        public void finishAndRemoveTask() {
19683            checkCaller();
19684
19685            synchronized (ActivityManagerService.this) {
19686                long origId = Binder.clearCallingIdentity();
19687                try {
19688                    if (!removeTaskByIdLocked(mTaskId, false)) {
19689                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19690                    }
19691                } finally {
19692                    Binder.restoreCallingIdentity(origId);
19693                }
19694            }
19695        }
19696
19697        @Override
19698        public ActivityManager.RecentTaskInfo getTaskInfo() {
19699            checkCaller();
19700
19701            synchronized (ActivityManagerService.this) {
19702                long origId = Binder.clearCallingIdentity();
19703                try {
19704                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19705                    if (tr == null) {
19706                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19707                    }
19708                    return createRecentTaskInfoFromTaskRecord(tr);
19709                } finally {
19710                    Binder.restoreCallingIdentity(origId);
19711                }
19712            }
19713        }
19714
19715        @Override
19716        public void moveToFront() {
19717            checkCaller();
19718            // Will bring task to front if it already has a root activity.
19719            startActivityFromRecentsInner(mTaskId, null);
19720        }
19721
19722        @Override
19723        public int startActivity(IBinder whoThread, String callingPackage,
19724                Intent intent, String resolvedType, Bundle options) {
19725            checkCaller();
19726
19727            int callingUser = UserHandle.getCallingUserId();
19728            TaskRecord tr;
19729            IApplicationThread appThread;
19730            synchronized (ActivityManagerService.this) {
19731                tr = recentTaskForIdLocked(mTaskId);
19732                if (tr == null) {
19733                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19734                }
19735                appThread = ApplicationThreadNative.asInterface(whoThread);
19736                if (appThread == null) {
19737                    throw new IllegalArgumentException("Bad app thread " + appThread);
19738                }
19739            }
19740            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19741                    resolvedType, null, null, null, null, 0, 0, null, null,
19742                    null, options, callingUser, null, tr);
19743        }
19744
19745        @Override
19746        public void setExcludeFromRecents(boolean exclude) {
19747            checkCaller();
19748
19749            synchronized (ActivityManagerService.this) {
19750                long origId = Binder.clearCallingIdentity();
19751                try {
19752                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19753                    if (tr == null) {
19754                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19755                    }
19756                    Intent intent = tr.getBaseIntent();
19757                    if (exclude) {
19758                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19759                    } else {
19760                        intent.setFlags(intent.getFlags()
19761                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19762                    }
19763                } finally {
19764                    Binder.restoreCallingIdentity(origId);
19765                }
19766            }
19767        }
19768    }
19769}
19770